@@ -92,57 +92,60 @@ The user will:
92922 . Enter their credentials
93933 . Complete 2FA if needed
9494
95- ### 4. Poll for Completion
95+ ### 4. Stream until completion
9696
97- On your backend, poll until authentication completes:
97+ On your backend, follow the connection's SSE stream until authentication completes:
9898
9999<CodeGroup >
100100``` typescript TypeScript
101- let state = await kernel .auth .connections .retrieve (auth .id );
101+ const events = await kernel .auth .connections .follow (auth .id );
102+ let finalState;
102103
103- while (state .flow_status === ' IN_PROGRESS' ) {
104- await new Promise (r => setTimeout (r , 2000 ));
105- state = await kernel .auth .connections .retrieve (auth .id );
104+ for await (const event of events ) {
105+ if (event .event === ' managed_auth_state' ) {
106+ finalState = event ;
107+ }
106108}
107109
108- if (state . status === ' AUTHENTICATED ' ) {
110+ if (finalState ?. flow_status === ' SUCCESS ' ) {
109111 console .log (' Authentication successful!' );
110112}
111113```
112114
113115``` python Python
114- state = await kernel.auth.connections.retrieve(auth.id)
116+ events = await kernel.auth.connections.follow(auth.id)
117+ final_state = None
115118
116- while state.flow_status == " IN_PROGRESS " :
117- await asyncio.sleep( 2 )
118- state = await kernel.auth.connections.retrieve(auth.id)
119+ async for event in events :
120+ if event.event == " managed_auth_state " :
121+ final_state = event
119122
120- if state.status == " AUTHENTICATED " :
123+ if final_state and final_state.flow_status == " SUCCESS " :
121124 print (" Authentication successful!" )
122125```
123126
124127``` go Go
125- state , err := client.Auth .Connections .Get (ctx, auth.ID )
126- if err != nil {
127- panic (err)
128- }
128+ events := client.Auth .Connections .FollowStreaming (ctx, auth.ID )
129+ authenticated := false
129130
130- for state.FlowStatus == kernel.ManagedAuthFlowStatusInProgress {
131- time.Sleep (2 * time.Second )
132- state, err = client.Auth .Connections .Get (ctx, auth.ID )
133- if err != nil {
134- panic (err)
131+ for events.Next () {
132+ event := events.Current ()
133+ if event.Event == " managed_auth_state" && event.FlowStatus == " SUCCESS" {
134+ authenticated = true
135135 }
136136}
137+ if err := events.Err (); err != nil {
138+ panic (err)
139+ }
137140
138- if state. Status == kernel. ManagedAuthStatusAuthenticated {
141+ if authenticated {
139142 fmt.Println (" Authentication successful!" )
140143}
141144```
142145</CodeGroup >
143146
144147<Info >
145- Poll every 2 seconds . The session expires after 20 minutes if not completed, and the flow times out after 10 minutes of waiting for user input.
148+ The SSE stream closes automatically when the flow succeeds, fails, expires, or is canceled . The session expires after 20 minutes if not completed, and the flow times out after 10 minutes of waiting for user input.
146149</Info >
147150
148151### 5. Use the Profile
@@ -216,14 +219,16 @@ const login = await kernel.auth.connections.login(auth.id);
216219// Send user to hosted page
217220console .log (' Login URL:' , login .hosted_url );
218221
219- // Poll for completion
220- let state = await kernel .auth .connections .retrieve (auth .id );
221- while (state .flow_status === ' IN_PROGRESS' ) {
222- await new Promise (r => setTimeout (r , 2000 ));
223- state = await kernel .auth .connections .retrieve (auth .id );
222+ // Stream state changes until the flow completes
223+ const events = await kernel .auth .connections .follow (auth .id );
224+ let finalState;
225+ for await (const event of events ) {
226+ if (event .event === ' managed_auth_state' ) {
227+ finalState = event ;
228+ }
224229}
225230
226- if (state . status === ' AUTHENTICATED ' ) {
231+ if (finalState ?. flow_status === ' SUCCESS ' ) {
227232 const browser = await kernel .browsers .create ({
228233 profile: { name: ' doordash-user-123' },
229234 stealth: true ,
@@ -235,10 +240,9 @@ if (state.status === 'AUTHENTICATED') {
235240```
236241
237242``` python Python
238- from kernel import Kernel
239- import asyncio
243+ from kernel import AsyncKernel
240244
241- kernel = Kernel ()
245+ kernel = AsyncKernel ()
242246
243247# Create connection
244248auth = await kernel.auth.connections.create(
@@ -252,13 +256,14 @@ login = await kernel.auth.connections.login(auth.id)
252256# Send user to hosted page
253257print (f " Login URL: { login.hosted_url} " )
254258
255- # Poll for completion
256- state = await kernel.auth.connections.retrieve(auth.id)
257- while state.flow_status == " IN_PROGRESS" :
258- await asyncio.sleep(2 )
259- state = await kernel.auth.connections.retrieve(auth.id)
259+ # Stream state changes until the flow completes
260+ events = await kernel.auth.connections.follow(auth.id)
261+ final_state = None
262+ async for event in events:
263+ if event.event == " managed_auth_state" :
264+ final_state = event
260265
261- if state.status == " AUTHENTICATED " :
266+ if final_state and final_state.flow_status == " SUCCESS " :
262267 browser = await kernel.browsers.create(
263268 profile = {" name" : " doordash-user-123" },
264269 stealth = True ,
@@ -274,7 +279,6 @@ package main
274279import (
275280 " context"
276281 " fmt"
277- " time"
278282
279283 " github.com/kernel/kernel-go-sdk"
280284 " github.com/kernel/kernel-go-sdk/shared"
@@ -304,20 +308,20 @@ func main() {
304308 // Send user to hosted page
305309 fmt.Println (" Login URL:" , login.HostedURL )
306310
307- // Poll for completion
308- state , err := client.Auth .Connections .Get (ctx, auth.ID )
309- if err != nil {
310- panic (err)
311- }
312- for state.FlowStatus == kernel.ManagedAuthFlowStatusInProgress {
313- time.Sleep (2 * time.Second )
314- state, err = client.Auth .Connections .Get (ctx, auth.ID )
315- if err != nil {
316- panic (err)
311+ // Stream state changes until the flow completes
312+ events := client.Auth .Connections .FollowStreaming (ctx, auth.ID )
313+ authenticated := false
314+ for events.Next () {
315+ event := events.Current ()
316+ if event.Event == " managed_auth_state" && event.FlowStatus == " SUCCESS" {
317+ authenticated = true
317318 }
318319 }
320+ if err := events.Err (); err != nil {
321+ panic (err)
322+ }
319323
320- if state. Status == kernel. ManagedAuthStatusAuthenticated {
324+ if authenticated {
321325 browser , err := client.Browsers .New (ctx, kernel.BrowserNewParams {
322326 Profile: shared.BrowserProfileParam {
323327 Name: kernel.String (" doordash-user-123" ),
0 commit comments