@@ -119,7 +119,7 @@ class _AuthCodeHttpServer6(_AuthCodeHttpServer):
119
119
120
120
class AuthCodeReceiver (object ):
121
121
# This class has (rather than is) an _AuthCodeHttpServer, so it does not leak API
122
- def __init__ (self , port = None ):
122
+ def __init__ (self , port = None , scheduled_actions = None ):
123
123
"""Create a Receiver waiting for incoming auth response.
124
124
125
125
:param port:
@@ -128,6 +128,12 @@ def __init__(self, port=None):
128
128
If your Identity Provider supports dynamic port, you can use port=0 here.
129
129
Port 0 means to use an arbitrary unused port, per this official example:
130
130
https://docs.python.org/2.7/library/socketserver.html#asynchronous-mixins
131
+
132
+ :param scheduled_actions:
133
+ For example, if the input is
134
+ ``[(10, lambda: print("Got stuck during sign in? Call 800-000-0000"))]``
135
+ then the receiver would call that lambda function after
136
+ waiting the response for 10 seconds.
131
137
"""
132
138
address = "127.0.0.1" # Hardcode, for now, Not sure what to expose, yet.
133
139
# Per RFC 8252 (https://tools.ietf.org/html/rfc8252#section-8.3):
@@ -141,6 +147,7 @@ def __init__(self, port=None):
141
147
# When this server physically listens to a specific IP (as it should),
142
148
# you will still be able to specify your redirect_uri using either
143
149
# IP (e.g. 127.0.0.1) or localhost, whichever matches your registration.
150
+ self ._scheduled_actions = sorted (scheduled_actions or []) # Make a copy
144
151
Server = _AuthCodeHttpServer6 if ":" in address else _AuthCodeHttpServer
145
152
# TODO: But, it would treat "localhost" or "" as IPv4.
146
153
# If pressed, we might just expose a family parameter to caller.
@@ -215,6 +222,10 @@ def get_auth_response(self, timeout=None, **kwargs):
215
222
time .sleep (1 ) # Short detection interval to make happy path responsive
216
223
if not t .is_alive (): # Then the thread has finished its job and exited
217
224
break
225
+ while (self ._scheduled_actions
226
+ and time .time () - begin > self ._scheduled_actions [0 ][0 ]):
227
+ _ , callback = self ._scheduled_actions .pop (0 )
228
+ callback ()
218
229
return result or None
219
230
220
231
def _get_auth_response (self , result , auth_uri = None , timeout = None , state = None ,
0 commit comments