How to use a python script to host and then visit a server without waiting for return

0

I'm writing a script that creates an html file, and then will need to host it, visit the local host, and take a screenshot. I can get it to do all of those things, but the only problem is that it won't try to take the screenshot until it gets a return from the command that starts the server. Meaning that the server will be closed already. I've tried solving this using asyncio, but it still doesn't seem to work. Here's the part of the code I'm having trouble with:

async def server():
    # host the directory
    await os.system ('python -m http.server')

async def screenshot():
    # cd to google chrome's default install path and call headless chrome from it
    os.chdir("C:\Program Files (x86)\Google\Chrome\Application")
    os.system('chrome  --headless --disable-gpu --enable-logging --screenshot="{}" --window-size=1920,1080 http://localhost:8000/{}'.format(Path(outpath,'images','{}_thumbnail.png'.format(file)),file))
    os.chdir (defaultpath)
    return print ('The image has been saved to {}'.format(str(Path(outpath,'images'))))

loop = asyncio.get_event_loop()

os.chdir(outpath)

asyncio.ensure_future(server())
loop.run_until_complete(screenshot())

await doesn't seem to work on the command to start the server. I have also tried using subprocess.call('python -m http.server', creationflags=0x00000008) as well as subprocess.call('python -m http.server', creationflags=0x00000010) to detach the server hosting process to another shell, but python still waits for it to return before continuing. (As a side note be careful if you decide to test those because 0x00000008 will be hidden when it runs and it's easy to forget about).

Does anyone know if there's a way to have one script do this, or will I have to create a second application to run the server while the screenshot is taken?

python
server
async-await
python-asyncio
asked on Stack Overflow Jul 18, 2018 by Thomas • edited Jul 18, 2018 by Thomas

2 Answers

1

Consider using threads to run both functions at the same time, that way the server function won't block the screenshot one:

from datetime import datetime
import time, threading

def server():
    print("Start Server:", datetime.now())
    time.sleep(5)
    print("Stopped Server:", datetime.now())

def screenshot():
    print("Took Screenshot", datetime.now())

if __name__ == '__main__':
    server_thread = threading.Thread(target=server)
    screenshot_thread = threading.Thread(target=screenshot)

    server_thread.start()
    screenshot_thread.start()

    server_thread.join()
    screenshot_thread.join()

The above printed:

Start Server: 2018-07-18 01:54:54.409359
Took Screenshot 2018-07-18 01:54:54.409359
Stopped Server: 2018-07-18 01:54:59.410503

You may also need to delay the screenshot function call to allow for the server to start up which you could do crudely with a time delay, for example.

answered on Stack Overflow Jul 18, 2018 by inkychris
0

I think what you want to get a snapshot as connecting own your url. arn't you?

I run the following code in 3.6 python. not 2.7 python.

Because I think, your code wrote in 2.7 python.

I hope to help for your problem.

import os
import os.path
import sys
import asyncio
import time

defaultpath = "C:\\Temp_Work"
outpath = "C:\\Temp_Work"

async def server():
    print('server start')
    # host the directory
    await os.system ('python -m http.server')    

async def screenshot():        
    print('screenshot start')
    # cd to google chrome's default install path and call headless chrome from it        
    os.chdir("C:\\Program Files (x86)\\Google\\Chrome\\Application")
    os.system('chrome.exe  --headless --disable-gpu --enable-logging --screenshot="C:\\Temp_Work\\test.jpg" --window-size=1920,1080 http://localhost:8000/good.jpg')
    os.chdir (defaultpath)
    #return  print ('The image has been saved to {}'.format(str(os.path(outpath,'images'))))
    return print('screenshot end')

print('app start')
loop = asyncio.get_event_loop()
os.chdir(outpath)
#asyncio.ensure_future(server())
loop.run_until_complete(screenshot())
loop.close()
print('finish')
answered on Stack Overflow Jul 18, 2018 by clem

User contributions licensed under CC BY-SA 3.0