Rob
Rob

Reputation: 3459

Waiting for all functions to return before returning value

Imagine I have a function like:

def func1():
    return int(requests.get('https://www.random.org/integers/?num=1&min=0&max=10&col=1&base=10&format=plain&rnd=new').text)

and I want to call this function three times, sum the responses and then return the sum squared or something simple. How can I do this so the three function calls are asynchronous but it waits for them all to return, a la Promise.all in Javascript?

I am using Python 2.

Upvotes: 0

Views: 444

Answers (3)

Irmen de Jong
Irmen de Jong

Reputation: 2847

Depending on your taste, and if you're okay with installing a 3rd party backport module https://pypi.python.org/pypi/futures you could also use concurrent.futures as a higher level interface to avoid dealing with threads and having an API more alike to the promises/futures you mentioned in your question:

from concurrent.futures import ThreadPoolExecutor
import requests

def func1():
    return int(requests.get('https://www.random.org/integers/?num=1&min=0&max=10&col=1&base=10&format=plain&rnd=new').text)

ex = ThreadPoolExecutor()
f1 = ex.submit(func1)
f2 = ex.submit(func1)
f3 = ex.submit(func1)

print(f1.result(), f2.result(), f3.result())

Upvotes: 0

zwer
zwer

Reputation: 25789

You need to use threading for that, the easiest would be via the multiprocessing.pool.ThreadPool package (don't let it fool you, it's not multiprocessing despite being in the package):

import requests
from multiprocessing.pool import ThreadPool

# let's make it a bit more flexible
RANDOM_URL = 'https://www.random.org/integers/'
RANDOM_PARAMS = {"num": 1, "min": 0, "max": 10, "col": 1, "base": 10,
                 "format": "plain", "rnd": "new"}

def func1(*args):  # args added to account for the dummy payload from pool.map
    return int(requests.get(RANDOM_URL, params=RANDOM_PARAMS).text)

pool = ThreadPool(processes=3)
response_sum = sum(pool.map(func1, range(3)))
print("Squared response: {}".format(response_sum**2))

Upvotes: 2

Sam Chats
Sam Chats

Reputation: 2321

For your purposes, I'm modifying the function a bit:

def func1():
    page = requests.get('https://www.random.org/integers/?num=1&min=0&max=10&col=1&base=10&format=plain&rnd=new').text
    num = extract_num(page) # Any parsing function that extracts the number and converts it to an integer type.
    cumulative += num # Sums up

Then, use threads:

import threading

cumulative = 0

for i in range(3): # Gets random numbers asynchronously.
    threading.Thread(target=func1).start()
print cumulative

Upvotes: 1

Related Questions