'How do you add a CSS style to a HTML file with a python http.server?

I have a simple http server running from python which returns an HTML file as a GET request. The HTMl file just has some input and it is sent correctly but is not styled even though it is linked to a CSS file. Here is the server.py:

from http.server import BaseHTTPRequestHandler, HTTPServer
import time

hostName = "localhost"
serverPort = 8080

class MyServer(BaseHTTPRequestHandler):
    def do_GET(self):
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.end_headers()
            h = open("main.html", "rb")
            self.wfile.write(h.read())
    def do_POST(s):
        if s.path == '/':
            s.path = './main.html'

if __name__ == "__main__":
    webServer = HTTPServer((hostName, serverPort), MyServer)
    print("Server started http://%s:%s" % (hostName, serverPort))

    try:
        webServer.serve_forever()
    except KeyboardInterrupt:
        pass

    webServer.server_close()
    print("Server stopped.")

main.html is this

<html>

<head>
    <link rel="stylesheet" href="./output.css">
</head>

<body>
    <h1 class="mx-auto text-center mt-8 px-0 py-8 border border-4 border-solid border-gray-600"
        style="width: 700!important;">CHECKBOX INPUT</h1>
    <div class="flex h-full mx-auto">
        <form action="">
            <div class="w-3/4 py-10 px-8">
                <table class="table-auto">

                    <thead>
                        <tr>
                            <th class="py-10 h-4">
                                <div class="mr-64">
                                    <input type="checkbox" class="form-checkbox h-8 w-8">
                                    <label class="ml-4">test</label>
                                </div>
                            </th>
                        </tr>
                        <tr>
                            <th class="py-10 h-4">
                                <div class="mr-64">
                                    <input type="checkbox" class="form-checkbox h-8 w-8">
                                    <label class="ml-4"></label>
                                </div>
                            </th>
                        </tr>
                        <tr>
                            <th class="py-10 h-4">
                                <div class="mr-64">
                                    <input type="checkbox" class="form-checkbox h-8 w-8">
                                    <label class="ml-4">test</label>
                                </div>
                            </th>
                        </tr>
                        <tr>
                            <th class="py-10 h-4">
                                <div class="mr-64">
                                    <input type="checkbox" class="form-checkbox h-8 w-8">
                                    <label class="ml-4">test</label>
                                </div>
                            </th>
                        </tr>
                        <tr>
                            <th class="px-4  py-10 h-4">
                                <div class="mx-auto">
                                    <span>TEXT INPUT:</span>
                                    <input type="text" class="form-input mt-4">
                                    <select>
                                        <option value="value1" selected>DROPDOWN</option>
                                        <option value="valeu2">Value 2</option>
                                        <option value="valeu3">Value 3</option>
                                    </select>
                                </div>

                            </th>
                        </tr>
                        <tr>
                            <th class="px-4  py-10 h-4">
                                <div class="mx-auto">

                                </div>

                            </th>
                        </tr>
                        <tr>
                            <th class="px-4  py-10 h-4">
                                <div class="mx-auto">
                                    <input type="submit" value="Submit" class="bg-gray-600 p-4 border-0 border-solid rounded-lg">
                                </div>

                            </th>
                        </tr>
                    </thead>

                </table>
            </div>
        </form>
    </div>
</body>

</html>

Even though the HTMl file is linked to output.css when I host the server it returns the HTML file without any styling

Thank you in advance



Solution 1:[1]

When your HTML file is loaded in browser it tries to load CSS file (./output.css). Since you serve this page over HTTP browser makes HTTP request to get this output.css file but apparently your server doesn't serve this CSS file.

Solution 2:[2]

Its really complicated to do so, because you have to create new server that serve your css file. **Better you used Powerfull & popular solutions likeFlask and Django **where you can configure these files easily. for more info about Flask https://pymbook.readthedocs.io/en/latest/flask.html

Solution 3:[3]

is your html file or css file in a folder? if so change in the html file the link to "[folder name]/output.css"

Solution 4:[4]

Hey I just had to figure this out myself. You've likely solved this already but incase anyone else stumbles across this, here's what I came up with, working great!

def do_GET(self):
    # Cache request
    path = self.path

    # Validate request path, and set type
    if path == "/resources/index.html":
        type = "text/html"
    elif path == "/resources/script.js":
        type = "text/javascript"
    elif path == "/resources/style.css":
        type = "text/css"
    elif path == "/favicon.ico":
        path = "/resources/favicon.ico"
        type = "image/x-icon"
    else:
        # Wild-card/default
        if not path == "/":
            print("UNRECONGIZED REQUEST: ", path)
            
        path = "/resources/index.html"
        type = "text/html"
    
    # Set header with content type
    self.send_response(200)
    self.send_header("Content-type", type)
    self.end_headers()
    
    # Open the file, read bytes, serve
    with open(path[1:], 'rb') as file: 
        self.wfile.write(file.read()) # Send

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 GProst
Solution 2 Jatin Pal
Solution 3 Suraj Rao
Solution 4