iruoy
iruoy

Reputation: 122

Can I make a `subprocess.Popen` call async?

I am trying to run whois on a bunch of domains from that I've got in a queue, but I think it's not working because the subprocess.Popen call is not async. Everything works, but is processing synchronous at the moment.

async def worker(name, queue):
    while True:
        # Get a domain out of the queue
        domain = await queue.get()

        print(f"\u001b[33m{name}\u001b[0m: {domain}", end="", flush=True)

        # Call `whois` on the domain
        whois = subprocess.Popen(["whois", domain], stdout=subprocess.PIPE)

        # Notify the queue that the domain has been processed
        queue.task_done()

        print(
            " " + "\u001b[32mAVAILABLE\u001b[0m"
            if whois.communicate()[0] == b"Domain Not Found\n"
            else "\u001b[31mUNAVAILABLE\u001b[0m"
        )

Upvotes: -1

Views: 949

Answers (1)

ShadowRanger
ShadowRanger

Reputation: 155438

asyncio provides its own subprocess facilities that you should use if you're trying to write async code. Don't use subprocess itself at all.

async def worker(name, queue):
    while True:
        # Get a domain out of the queue
        domain = await queue.get()

        print(f"\u001b[33m{name}\u001b[0m: {domain}", end="", flush=True)

        # Call `whois` on the domain
        whois = asyncio.create_subprocess_exec(["whois", domain], stdout=subprocess.PIPE)

        # Notify the queue that the domain has been processed
        queue.task_done()

        whois_out, _ = await whois.communicate()  # Avoid overly dense code, await and
                                                  # unpack first, then print
        print(
            " " + "\u001b[32mAVAILABLE\u001b[0m"
            if whois_out == b"Domain Not Found\n"
            else "\u001b[31mUNAVAILABLE\u001b[0m"
        )

Upvotes: 1

Related Questions