I'm trying to set up very basic http server on my hosting(centos)
The script is:
#!/usr/bin/env python3.8
from http.server import HTTPServer, BaseHTTPRequestHandler
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, world!')
httpd = HTTPServer(('0.0.0.0', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()
Everything looks normal: ss -t -a -n
LISTEN 0 5 0.0.0.0:8080 0.0.0.0:*
But when im trying to get to my websitename:8080 nothing is happening and i get connection timed out response.
I've been googling about http, networking, even centos for a few days, got lots of usefull information but i still have no idea what's going on here.
Ty for your time!
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
this is my Python3 project hiearchy:
projet
\
script.py
web
\
index.html
From script.py, I would like to run a http server which serve the content of the web folder.
Here is suggested this code to run a simple http server:
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
but this actually serve project, not web. How can I specify the path of the folder I want to serve?
In Python 3.7 SimpleHTTPRequestHandler can take a directory argument:
import http.server
import socketserver
PORT = 8000
DIRECTORY = "web"
class Handler(http.server.SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=DIRECTORY, **kwargs)
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
and from the command line:
python -m http.server --directory web
To get a little crazy... you could make handlers for arbitrary directories:
def handler_from(directory):
def _init(self, *args, **kwargs):
return http.server.SimpleHTTPRequestHandler.__init__(self, *args, directory=self.directory, **kwargs)
return type(f'HandlerFrom<{directory}>',
(http.server.SimpleHTTPRequestHandler,),
{'__init__': _init, 'directory': directory})
with socketserver.TCPServer(("", PORT), handler_from("web")) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
If you just want serve static file you can do it by running SimpleHTTPServer module using python 2:
python -m SimpleHTTPServer
Or with python 3:
python3 -m http.server
This way you do not need to write any script.
https://docs.python.org/3/library/http.server.html#http.server.SimpleHTTPRequestHandler
This class serves files from the current directory and below, directly
mapping the directory structure to HTTP requests.
So you just need to change the current directory prior to starting the server - see os.chdir
eg:
import http.server
import socketserver
import os
PORT = 8000
web_dir = os.path.join(os.path.dirname(__file__), 'web')
os.chdir(web_dir)
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
Just for completeness, here's how you can setup the actual server classes to serve files from an arbitrary directory:
try
# python 2
from SimpleHTTPServer import SimpleHTTPRequestHandler
from BaseHTTPServer import HTTPServer as BaseHTTPServer
except ImportError:
# python 3
from http.server import HTTPServer as BaseHTTPServer, SimpleHTTPRequestHandler
class HTTPHandler(SimpleHTTPRequestHandler):
"""This handler uses server.base_path instead of always using os.getcwd()"""
def translate_path(self, path):
path = SimpleHTTPRequestHandler.translate_path(self, path)
relpath = os.path.relpath(path, os.getcwd())
fullpath = os.path.join(self.server.base_path, relpath)
return fullpath
class HTTPServer(BaseHTTPServer):
"""The main server, you pass in base_path which is the path you want to serve requests from"""
def __init__(self, base_path, server_address, RequestHandlerClass=HTTPHandler):
self.base_path = base_path
BaseHTTPServer.__init__(self, server_address, RequestHandlerClass)
Then you can set any arbitrary path in your code:
web_dir = os.path.join(os.path.dirname(__file__), 'web')
httpd = HTTPServer(web_dir, ("", 8000))
httpd.serve_forever()
There's a shorter method for Python 3+:
import functools
Handler = functools.partial(http.server.SimpleHTTPRequestHandler, directory='/my/dir/goes/here')
You also can run the command line with
python3 -m http.server -d web 8000
Another easy method to serve from a specific directory.
Since you really only need to set the directory parameter for the SimpleHTTPRequestHandler, you can use functools.partial to prepare the handler class without instantiating the class.
from functools import partial
from http.server import HTTPServer, SimpleHTTPRequestHandler
from pathlib import Path
def start_httpd(directory: Path, port: int = 8000):
print(f"serving from {directory}...")
handler = partial(SimpleHTTPRequestHandler, directory=directory)
httpd = HTTPServer(('localhost', port), handler)
httpd.serve_forever()
If you just need a modern web static server,
deno is an alternative file server without any code.
install deno with single line
https://github.com/denoland/deno_install#deno_install
install file server with single line
deno install --allow-net --allow-read https://deno.land/std#0.125.0/http/file_server.ts
use deno file-server
file_server . --port=<port>
# Downloading https://deno.land/std#0.125.0/http/file_server.ts...
# HTTP server listening on http://0.0.0.0:<port>/
read more https://deno.land/manual/examples/file_server#using-the-codestdhttpcode-file-server
Building a simple file server using the SimpleHTTPServer module in Python, however I'm running into issues when trying to get the IP from a connecting client. Here is what I have..
import SimpleHTTPServer
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", 8080), Handler)
print "Serving local directory"
while True:
httpd.handle_request()
print Handler.client_address[0]
When a client connects I get..
AttributeError: class SimpleHTTPRequestHandler has no attribute 'client_address'
I know this is because I haven't instantiated the class yet, but is there another way to get the IP from the client without having to create a handler instance? The client's IP is outputted to the console when a connection is made, I just need a way to grab that IP within my script.
Thanks!
Indeed, the Handler class object is unrelated to specific instances. Set up your own handler class, like this:
import SimpleHTTPServer
import SocketServer
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def handle_one_request(self):
print(self.client_address[0])
return SimpleHTTPServer.SimpleHTTPRequestHandler.handle_one_request(self)
print("Serving local directory")
httpd = SocketServer.TCPServer(("", 8080), MyHandler)
while True:
httpd.handle_request()
I am trying to set up a simple web service but when I do an HTTP request to the port 8080 of my server nothing happens...
I have discovered that the simple python server that i have set up listens on the 8080 port of the primary private IP and not on the public IP port.
How can I send the HTTP requests to the python script? Do I have to NAT?
I am on ubuntu 14.04 server
This is the simple python web server
from BaseHTTPServer import BaseHTTPRequestHandler
import urlparse
class GetHandler(BaseHTTPRequestHandler):
def do_GET(self):
parsed_path = urlparse.urlparse(self.path)
self.wfile.write(parsed_path.query[2:])
return
if __name__ == '__main__':
from BaseHTTPServer import HTTPServer
server = HTTPServer(("0.0.0.0", 8080), GetHandler)
print 'Starting server, use <Ctrl-C> to stop'
server.serve_forever()
Change the line:
server = HTTPServer(("0.0.0.0", 8080), GetHandler)
To use the IP address of the public IP network adapter instead of "0.0.0.0"
The problem was that I didn't set a rule for port 8080! Thank you to everybody!