I need to assign a PID to a python script packaged to an .exe with Py2Installer.
The script starts a SimpleHTTPServer loop and opens a page in the current dir; I need to check if it's already running before it starts and stop it gracefully in that case.
Here's the code:
import SimpleHTTPServer
import SocketServer
import webbrowser
PORT = 8945
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
webbrowser.open('http://localhost:8945')
# print "serving at port", PORT
httpd.serve_forever()
The problem is that I don't want to stop any "python" instance on a production machine and my taskkill can't view any SimpleHTTPServer process ID (because there is none, in fact).
Is it possible to run a similar check inside my script or do you know any workaround?
Thank you in advance.
Related
When I run a local host server to view my html files, I usually use the command line prompt:
python -m http.server 8000
However, I want to be able to do this from within a .py file, and I'm struggling.
Ideally when running the py file it should launch the server, open the localhost in the default web browser, and then remain open until the user types in a keyword, like 'exit'. As per the http.server documentation, my current code looks like this:
import http.server
import socketserver
import webbrowser
PORT = 8000
URL = f'localhost:{PORT}/MapViz.html'
def run():
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("Enjoy your visualization!")
httpd.serve_forever()
if __name__ == "__main__":
run()
webbrowser.open_new(URL)
I know at the moment it has nothing to close the server after the user is done, but I'm just struggling to get it to open the browser first. It seems like serve_forever() is not the right tool for the job, but I'm not sure what is.
Also, do I need to worry about closing the socket? I've always been able to use a with open(x) as file: format for files to not worry about closing them, but I had an issue while messing with this where I got a Windows error 10048, stating that the socket was still being used, so maybe it's also not closing correctly.
Thank you!
Here is the solution I am using!
import http.server
import socketserver
import webbrowser
import threading
import sys
PORT = 8000
URL = f'http://localhost:{PORT}/MapViz.html'
def run():
Handler = http.server.SimpleHTTPRequestHandler
global httpd
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f"Enjoy your visualization!")
httpd.serve_forever()
def maintain():
webbrowser.open_new(URL)
while True:
user_input = input()
if user_input == 'EXIT' or user_input == 'exit':
print('Shutting down! Run this .exe again to view your visualization again.')
threading.Timer(0.1, httpd.shutdown).start()
break
if __name__ == '__main__':
threading.Timer(1.0, maintain).start()
run()
I tweaked the code Michael gave me ever so slightly and had threading.Timer call an entirely new function, which both opened the window in a browser and checked for the kill-word.
I am sure my shutdown is not the most efficient way, but does what I need it to. I will definitely need to look into more threading examples to find how best
I want to launch Python HTTPServer on heroku. Note that this is no Python framework. The code snippet is attached below. How will I be able to launch this server on Heroku? I am able to run this server on my local machine. But I want it deployed on Heroku. Please provide insights.
Server Code:
import http.server
from http.server import HTTPServer, BaseHTTPRequestHandler
import socketserver
import threading
PORT = 5001
class myHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.write("Heroku is awesome")
class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
try:
server = ThreadedTCPServer(('', PORT), myHandler)
print ('Started httpserver on port ' , PORT)
ip,port = server.server_address
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
allow_reuse_address = True
server.serve_forever()
except KeyboardInterrupt:
print ('CTRL + C RECEIVED - Shutting down the REST server')
server.socket.close()
When heroku runs your process, it defines the environment variable PORT to the internal port you should expose your server on. Your server will then be accessible from the internet on port 80, the default HTTP port.
Python can access environment variables with os.environ.
So you can use:
PORT = environ['PORT']
os.envron docs here
You can read more about how Heroku handles ports here.
Create a Procfile with a single line:
web: python yourscript.py
I am using SimpleHTTPServer in jupyter notebook like this:
import SimpleHTTPServer
import SocketServer
PORT = 8000
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
It works good, but how can I stop it later in next input block?
The answer is that you can't.
You're unable to reference previous cells (or the results of) inside of Jupyter Notebook - see this open issue for more details on the discussion.
This means you can't manipulate the object once you've used the serve_forever() function.
It may however be possible to rewrite serve_forever to fit your needs. Currently it will literally serve no matter what but adding a condition that allows you to connect and issue a 'shutdown' command would circumvent the need to call up the object later. You could just connect to the socket and issue a customised header that the TCP server would pick up and respond to.
As a quick example to start you on this path:
class StoppableRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
def serve_forever(self):
while not self.stopped:
self.handle_request()
def not_forever(self):
# Called from another function when a custom header is detected
self.stopped = True
self.server_close()
the server are running in background you need to search the PID an kill it like:
netstat -tulpn
Netstat out:
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 12332/python
Kill PID with pkill or kill:
kill 12332
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?
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...)
I'm a total newbie when it comes to servers, so this question my sound silly to you, but I stucked and I need you help once more.
I have written a simple server in python, which looks like this:
#!/usr/bin/env python
from socket import *
import time
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', 8888))
s.listen(5)
while 1:
client,addr = s.accept()
print 'Connected to ', addr
client.send(time.ctime(time.time()))
client.close()
So when i write localhost:8888 in my browser, i get the message with the current server time.
The next thing i want to do, is to configure my server to allow opening various files from my computer i.e. html or text ones. So when I write in my browser localhost:8888/text.html, this file opens. Where do i start with that?
I should mention I'm using linux mint and don't want to use any existing framework. I want to fully understand how the servers are working and responding.
Try this:
Create a script named webserver.py
import SimpleHTTPServer
import SocketServer
PORT = 8888
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
Create a file named text.html and place it on the same dir where your webserver.py script is.
Run python webserver.py
Navigate to http://localhost:8888/text.html