Eric Palmer
Eric Palmer

Reputation: 79

Execuring python web server in parallel with with other code

I'm wanting to run a web server localing in a thread or as a parallel process and then to be able query urls from that web server in the same python program. I'm building html self motivational slides and will then use qt to display them in a web browser.

The web server will only be queried locally and at a very low volume.

I've tried to do this using threading and now this program using multiprocessing. I get similar stack traces from both.

My Question: How can I get the web server running and yet not block the code that executes after the web server starts?

import http.server
import socketserver
import os
from multiprocessing import Process
import time

def run_webserver():
    cwd = os.getcwd()
    os.chdir("./www/public")
    PORT = 8002
    Handler = http.server.SimpleHTTPRequestHandler

    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        print("serving at port", PORT)

    return httpd

if __name__ == '__main__':
    httpd = run_webserver()
    p = Process(target=httpd.serve_forever, args=())
    p.start()
    p.join()

    # do other work
    for i in range(200):
        print(str(i))
        time.sleep(500)

serving at port 8002
Process Process-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/    process.py", line 249, in _bootstrap
    self.run()
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/multiprocessing/    process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socketserver.py", line     233, in serve_forever
    selector.register(self, selectors.EVENT_READ)
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/selectors.py", line 351,     in register
    key = super().register(fileobj, events, data)
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/selectors.py", line 237,     in register
    key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/selectors.py", line 224,     in _fileobj_lookup
    return _fileobj_to_fd(fileobj)
  File "/usr/local/Cellar/python3/3.6.0_1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/selectors.py", line 41,     in _fileobj_to_fd
    raise ValueError("Invalid file descriptor: {}".format(fd))
ValueError: Invalid file descriptor: -1

Upvotes: 3

Views: 2182

Answers (1)

Eric Palmer
Eric Palmer

Reputation: 79

Okay got it to work.

import http.server
import socketserver
import os
import multiprocessing
import time

def run_webserver():
    os.chdir("./www/public")
    PORT = 8002
    Handler = http.server.SimpleHTTPRequestHandler
    httpd = socketserver.TCPServer(('0.0.0.0', PORT), Handler)

    #the following throws an exception
    #with socketserver.TCPServer(("0.0.0.0", PORT), Handler) as httpd:
    #    print("serving at port", PORT)

    httpd.serve_forever(poll_interval=0.5)

    return

if __name__ == '__main__':
    p = multiprocessing.Process(target=run_webserver, args=())
    p.daemon = True
    p.start()

    # do other work
    for i in range(200):
        print(str(i))
        time.sleep(1)

Upvotes: 2

Related Questions