voici la hiérarchie de mon projet Python3:
projet
\
script.py
web
\
index.html
De script.py
, Je voudrais lancer un serveur http qui sert le contenu du dossier web
.
Ici on suggère ce code pour exécuter un serveur http simple:
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
httpd = socketserver.TCPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
mais cela sert en fait project
, pas web
. Comment puis-je spécifier le chemin du dossier que je veux servir?
https://docs.python.org/3/library/http.server.html#http.server.SimpleHTTPRequestHandler
Cette classe sert les fichiers du répertoire en cours et des répertoires inférieurs, mappant directement la structure de répertoires aux requêtes HTTP.
Il suffit donc de changer le répertoire en cours avant de démarrer le serveur - voir os.chdir
par exemple:
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()
Si vous voulez seulement servir un fichier statique, vous pouvez le faire en exécutant le module SimpleHTTPServer avec python 2:
python -m SimpleHTTPServer
Ou avec python 3:
python3 -m http.server
De cette façon, vous n'avez pas besoin d'écrire de script.
Dans Python 3.7 SimpleHTTPRequestHandler
peut prendre un argument de directory
.) :
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()
et depuis la ligne de commande:
python -m http.server --directory web
Pour devenir un peu fou ... vous pouvez créer des gestionnaires pour des répertoires arbitraires:
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()
Juste pour être complet, voici comment vous pouvez configurer les classes de serveur afin de servir les fichiers depuis un répertoire arbitraire:
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)
Ensuite, vous pouvez définir n'importe quel chemin arbitraire dans votre code:
web_dir = os.path.join(os.path.dirname(__file__), 'web')
httpd = HTTPServer(web_dir, ("", 8000))
httpd.serve_forever()