Skip to content

Commit 1d37d10

Browse files
frier17frier17
andauthored
Dev util delegate (#130)
* added function delegate_task to utils.py * updated file structure * updated api.py to include delegate_task --------- Co-authored-by: frier17 <aniefiok.friday@gmail.com>
1 parent 337f9e7 commit 1d37d10

4 files changed

Lines changed: 61 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,4 @@ coverage.xml
4747
# Django stuff:
4848
*.log
4949
*.pot
50+
.idea/

blockcypher/api.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from .utils import compress_txn_outputs
1919
from .utils import get_txn_outputs_dict
2020
from .utils import uses_only_hash_chars
21+
from .utils import delegate_task
2122

2223
from .constants import COIN_SYMBOL_MAPPINGS
2324

blockcypher/utils.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import re
2+
from concurrent.futures.thread import ThreadPoolExecutor
3+
from functools import partial
4+
from typing import Callable, Sequence, Tuple, List
25

36
from .constants import SHA_COINS, SCRYPT_COINS, ETHASH_COINS, COIN_SYMBOL_SET, COIN_SYMBOL_MAPPINGS, FIRST4_MKEY_CS_MAPPINGS_UPPER, UNIT_CHOICES, UNIT_MAPPINGS
47
from .crypto import script_to_address
@@ -521,3 +524,47 @@ def is_valid_address_for_coinsymbol(b58_address, coin_symbol):
521524
if is_valid_address(b58_address):
522525
return True
523526
return False
527+
528+
529+
def delegate_task(task: Callable, workers: int = 2, use_max: bool = False, args: List | Tuple = None, **kwargs):
530+
"""
531+
Execute a wrapped function on separate thread using ThreadPoolExecutor.
532+
The result of executing the wrapped function is passed to another system or caller.
533+
This function should be used for accessing blockchain operations that are IO bound
534+
535+
:param task: a function or any callable that will be executed on a separate thread
536+
:type task: callable
537+
:param workers: the number of threads in the thread pool for executing the wrapped function
538+
:type workers: int
539+
:param use_max: boolean flag to indicate if the maximum system thread pool should be used.
540+
:type use_max: bool
541+
:param args: list or tuple of argument to be passed to the task or function being executed
542+
:type args: list | tuple
543+
:param kwargs: mapping of keyword arguments to be passed to the task or function to be executed
544+
:type kwargs: dict
545+
:return: Returns the result of executing the callable or function
546+
:rtype: Any
547+
548+
Example
549+
=======
550+
>>> from blockcypher import get_transaction_details
551+
>>> tranx = 'f854aebae95150b379cc1187d848d58225f3c4157fe992bcd166f58bd5063449'
552+
>>> result = delegate_task(get_transaction_details, workers=2, use_max=False, args=[tranx])
553+
>>> print(result)
554+
"""
555+
if workers < 0:
556+
workers = 2
557+
if workers > 5:
558+
workers = 5
559+
if use_max:
560+
workers = 5
561+
with ThreadPoolExecutor(max_workers=workers) as ex:
562+
if args and kwargs:
563+
future = ex.submit(task, *args, **kwargs)
564+
elif args and not kwargs:
565+
future = ex.submit(task, *args)
566+
elif kwargs and not args:
567+
future = ex.submit(task, **kwargs)
568+
else:
569+
future = ex.submit(task)
570+
return future.result()

test_blockcypher.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import unittest
22

3-
from blockcypher.utils import is_valid_hash
3+
from blockcypher.utils import is_valid_hash, delegate_task
44

55
from blockcypher import simple_spend, simple_spend_p2sh
66
from blockcypher import get_broadcast_transactions, get_transaction_details
@@ -569,5 +569,16 @@ def test_register_btc_wallet(self):
569569
is_hd_wallet=True)
570570

571571

572+
class TestDelegateTask(unittest.TestCase):
573+
574+
def test_delegate(self):
575+
tranx = 'f854aebae95150b379cc1187d848d58225f3c4157fe992bcd166f58bd5063449'
576+
result = delegate_task(get_transaction_details, workers=2, use_max=False, args=[tranx])
577+
self.assertIsNotNone(result)
578+
self.assertNotIn('errors', result)
579+
self.assertIn('hash', result)
580+
self.assertEquals(result['hash'], tranx)
581+
582+
572583
if __name__ == '__main__':
573584
unittest.main(failfast=True)

0 commit comments

Comments
 (0)