88from flask import copy_current_request_context , has_request_context , request
99from werkzeug .exceptions import BadRequest
1010
11+ from typing import Optional , Iterable , Dict , Any , Callable
12+
1113from ..deque import LockableDeque
1214from ..utilities import TimeoutTracker
1315
@@ -25,12 +27,12 @@ class ActionThread(threading.Thread):
2527
2628 def __init__ (
2729 self ,
28- action ,
29- target = None ,
30- name = None ,
31- args = None ,
32- kwargs = None ,
33- daemon = True ,
30+ action : str ,
31+ target : Optional [ Callable ] = None ,
32+ name : Optional [ str ] = None ,
33+ args : Optional [ Iterable [ Any ]] = None ,
34+ kwargs : Optional [ Dict [ str , Any ]] = None ,
35+ daemon : bool = True ,
3436 default_stop_timeout : int = 5 ,
3537 log_len : int = 100 ,
3638 ):
@@ -39,34 +41,32 @@ def __init__(
3941 group = None ,
4042 target = target ,
4143 name = name ,
42- args = args ,
43- kwargs = kwargs ,
44+ args = args or () ,
45+ kwargs = kwargs or {} ,
4446 daemon = daemon ,
4547 )
4648
47- # Safely populate missing arguments
48- args = args or ()
49- kwargs = kwargs or {}
50-
5149 # Action resource corresponding to this action object
5250 self .action = action
5351
5452 # A UUID for the ActionThread (not the same as the threading.Thread ident)
5553 self ._ID = uuid .uuid4 () # Task ID
5654
5755 # Event to track if the task has started
58- self .started = threading .Event ()
56+ self .started : threading . Event = threading .Event ()
5957 # Event to track if the user has requested stop
60- self .stopping = threading .Event ()
61- self .default_stop_timeout = default_stop_timeout
58+ self .stopping : threading . Event = threading .Event ()
59+ self .default_stop_timeout : int = default_stop_timeout
6260
6361 # Make _target, _args, and _kwargs available to the subclass
64- self ._target = target
65- self ._args = args
66- self ._kwargs = kwargs
62+ self ._target : Optional [ Callable ] = target
63+ self ._args : Iterable [ Any ] = args or ()
64+ self ._kwargs : Dict [ str , Any ] = kwargs or {}
6765
6866 # Nice string representation of target function
69- self .target_string = f"{ self ._target } (args={ self ._args } , kwargs={ self ._kwargs } )"
67+ self .target_string : str = (
68+ f"{ self ._target } (args={ self ._args } , kwargs={ self ._kwargs } )"
69+ )
7070
7171 # copy_current_request_context allows threads to access flask current_app
7272 if has_request_context ():
@@ -82,14 +82,14 @@ def __init__(
8282
8383 # Private state properties
8484 self ._status : str = "pending" # Task status
85- self ._return_value = None # Return value
86- self ._request_time = datetime .datetime .now ()
87- self ._start_time = None # Task start time
88- self ._end_time = None # Task end time
85+ self ._return_value : Optional [ Any ] = None # Return value
86+ self ._request_time : datetime . datetime = datetime .datetime .now ()
87+ self ._start_time : Optional [ datetime . datetime ] = None # Task start time
88+ self ._end_time : Optional [ datetime . datetime ] = None # Task end time
8989
9090 # Public state properties
91- self .progress : int = None # Percent progress of the task
92- self .data = {} # Dictionary of custom data added during the task
91+ self .progress : Optional [ int ] = None # Percent progress of the task
92+ self .data : dict = {} # Dictionary of custom data added during the task
9393 self ._log = LockableDeque (
9494 None , log_len
9595 ) # The log will hold dictionary objects with log information
@@ -100,14 +100,14 @@ def __init__(
100100 ) # Lock obtained while self._target is running
101101
102102 @property
103- def id (self ):
103+ def id (self ) -> uuid . UUID :
104104 """
105105 UUID for the thread. Note this not the same as the native thread ident.
106106 """
107107 return self ._ID
108108
109109 @property
110- def output (self ):
110+ def output (self ) -> Any :
111111 """
112112 Return value of the Action function. If the Action is still running, returns None.
113113 """
@@ -119,7 +119,7 @@ def log(self):
119119 return list (logdeque )
120120
121121 @property
122- def status (self ):
122+ def status (self ) -> str :
123123 """
124124 Current running status of the thread.
125125
@@ -136,19 +136,19 @@ def status(self):
136136 return self ._status
137137
138138 @property
139- def dead (self ):
139+ def dead (self ) -> bool :
140140 """
141141 Has the thread finished, by any means (return, exception, termination).
142142 """
143143 return not self .is_alive ()
144144
145145 @property
146- def stopped (self ):
146+ def stopped (self ) -> bool :
147147 """Has the thread been cancelled"""
148148 return self .stopping .is_set ()
149149
150150 @property
151- def cancelled (self ):
151+ def cancelled (self ) -> bool :
152152 """Alias of `stopped`"""
153153 return self .stopped
154154
@@ -162,7 +162,7 @@ def update_progress(self, progress: int):
162162 # Update progress of the task
163163 self .progress = progress
164164
165- def update_data (self , data : dict ):
165+ def update_data (self , data : Dict [ Any , Any ] ):
166166 """
167167
168168 :param data: dict:
@@ -183,7 +183,7 @@ def run(self):
183183 # an argument that has a member that points to the thread.
184184 del self ._target , self ._args , self ._kwargs
185185
186- def _thread_proc (self , f ):
186+ def _thread_proc (self , f : Callable ):
187187 """Wraps the target function to handle recording `status` and `return` to `state`.
188188 Happens inside the task thread.
189189
@@ -228,7 +228,7 @@ def wrapped(*args, **kwargs):
228228
229229 return wrapped
230230
231- def get (self , block = True , timeout = None ):
231+ def get (self , block : bool = True , timeout : Optional [ int ] = None ):
232232 """Start waiting for the task to finish before returning
233233
234234 :param block: (Default value = True)
@@ -275,7 +275,7 @@ def _async_raise(self, exc_type):
275275 % (exc_type , self .name , self .ident , result )
276276 )
277277
278- def _is_thread_proc_running (self ):
278+ def _is_thread_proc_running (self ) -> bool :
279279 """Test if thread funtion (_thread_proc) is running,
280280 by attemtping to acquire the lock _thread_proc acquires at runtime.
281281
@@ -285,13 +285,13 @@ def _is_thread_proc_running(self):
285285 :rtype: bool
286286
287287 """
288- could_acquire = self ._running_lock .acquire (0 )
288+ could_acquire = self ._running_lock .acquire (False )
289289 if could_acquire :
290290 self ._running_lock .release ()
291291 return False
292292 return True
293293
294- def terminate (self , exception = ActionKilledException ):
294+ def terminate (self , exception = ActionKilledException ) -> bool :
295295 """
296296
297297 :param exception: (Default value = ActionKilledException)
@@ -314,7 +314,7 @@ def terminate(self, exception=ActionKilledException):
314314 self .progress = None
315315 return True
316316
317- def stop (self , timeout = None , exception = ActionKilledException ):
317+ def stop (self , timeout = None , exception = ActionKilledException ) -> bool :
318318 """Sets the threads internal stopped event, waits for timeout seconds for the
319319 thread to stop nicely, then forcefully kills the thread.
320320
0 commit comments