@@ -119,7 +119,7 @@ class _AuthCodeHttpServer6(_AuthCodeHttpServer):
119119
120120class AuthCodeReceiver (object ):
121121 # 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 ):
123123 """Create a Receiver waiting for incoming auth response.
124124
125125 :param port:
@@ -128,6 +128,12 @@ def __init__(self, port=None):
128128 If your Identity Provider supports dynamic port, you can use port=0 here.
129129 Port 0 means to use an arbitrary unused port, per this official example:
130130 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.
131137 """
132138 address = "127.0.0.1" # Hardcode, for now, Not sure what to expose, yet.
133139 # Per RFC 8252 (https://tools.ietf.org/html/rfc8252#section-8.3):
@@ -141,6 +147,7 @@ def __init__(self, port=None):
141147 # When this server physically listens to a specific IP (as it should),
142148 # you will still be able to specify your redirect_uri using either
143149 # IP (e.g. 127.0.0.1) or localhost, whichever matches your registration.
150+ self ._scheduled_actions = sorted (scheduled_actions or []) # Make a copy
144151 Server = _AuthCodeHttpServer6 if ":" in address else _AuthCodeHttpServer
145152 # TODO: But, it would treat "localhost" or "" as IPv4.
146153 # If pressed, we might just expose a family parameter to caller.
@@ -215,6 +222,10 @@ def get_auth_response(self, timeout=None, **kwargs):
215222 time .sleep (1 ) # Short detection interval to make happy path responsive
216223 if not t .is_alive (): # Then the thread has finished its job and exited
217224 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 ()
218229 return result or None
219230
220231 def _get_auth_response (self , result , auth_uri = None , timeout = None , state = None ,
0 commit comments