Apara
Apara

Reputation: 374

How can I run a local server and open urls from the same python program?

I want to start a local server and then open a link with a browser from the same python program.

This is what I tried (a very naive and foolish attempt):

from subprocess import call
import webbrowser

call(["python", "-m", "SimpleHTTPServer"]) #This creates a server at port:8000
webbrowser.open_new_tab("some/url")

However, the program doesn't go to the second statement because the server is still running in the background. To open the browser, I need to exit the server which defeats the purpose of running the server.

Can anyone help me by suggesting a working solution?

Upvotes: 1

Views: 1375

Answers (1)

Simon Fromme
Simon Fromme

Reputation: 3174

You could start your web server in a daemon thread (a Python program exits if only daemon threads are left) and then make your requests from the main thread.

The only problem then is to synchronize your main thread to the server thread, since the HTTP-server will need some time to start up and won't handle any requests until this point. I am not aware of an easy and clean solution to do that, but you could (somewhat hackish) just pause your main thread for a number seconds (possibly shorter) and start making requests only after this. Another option would be to just send requests to the webserver from the very beginning and expect them to fail for some amount of time.

Here is a small sample script with a simple HTTP webserver that serves content from the local file system over TCP on localhost:8080 and a sample request, requesting a file foo.txt from the directory the webserver (and in this case also the script) was started in.

import sys
import requests
import threading
import time

from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

# set up the HTTP server and start it in a separate daemon thread
httpd = HTTPServer(('localhost', 8080), SimpleHTTPRequestHandler)
thread = threading.Thread(target=httpd.serve_forever)
thread.daemon = True

# if startup time is too long we might want to be able to quit the program
try:
    thread.start()
except KeyboardInterrupt:
    httpd.shutdown()
    sys.exit(0)

# wait until the webserver finished starting up (maybe wait longer or shorter...)
time.sleep(5)

# start sending requests
r = requests.get('http://localhost:8080/foo.txt')

print r.status_code
# => 200 (hopefully...)

Upvotes: 1

Related Questions