2

I would like to make a HTTP request (PYTHON) with a web server that displays a data from a .txt file.

I have this data1.txt file that contains:

bonjour

and here is my code webserver.py:

#!/usr/bin/python
from http.server import BaseHTTPRequestHandler,HTTPServer
    
class myHandler(BaseHTTPRequestHandler):
    def do_GET(self):

        ###############################

        File = open('data1.txt',"r")
        if(File == None):
            print("File Not Found..")
        else:
            while(True):
                # extracting data from records 
                record = File.readline()
                if (record == ''): break
        File.close()

        ###############################


        self.send_response(200)
        self.send_header('Content-type','text/html')
        self.end_headers()
        self.wfile.write(
            b"Hello from <b>Raspberry Pi</b> running <b><i>Python</i></b>")
        self.wfile.write(
            b"<a href='http://helloraspberrypi.blogspot.com'>Hello Raspberry Pi</>")
        self.wfile.write(
            b"$record" )
        return

try:
    server = HTTPServer(('localhost', 8080), myHandler)
    print ('HTTPServer started')
    server.serve_forever()
    
except KeyboardInterrupt:
    print ('server.socket.close()')
    server.socket.close()

I would like to display bonjour thanks to the following line self.wfile.write(b"$record" ) from the variable record which corresponds to bonjour: record = File.readline() = bonjour

My issue is that I don't know how to call the variable, I tried with $record but it's not working.

Reinderien
  • 11,755
  • 5
  • 49
  • 77
Camille BOUQUET
  • 445
  • 1
  • 6
  • 18
  • Is it strictly necessary that you use a text file? This is easily possible without one, particularly for a single string. – Reinderien Jul 21 '21 at 13:40
  • Wouldn't you just use `self.wfile.write(record)`? – Scott Hunter Jul 21 '21 at 13:42
  • Your code would not have interpreted as-is. I have made an edit that guesses what your indentation actually is. – Reinderien Jul 21 '21 at 13:43
  • @Scott Hunter: `self.wfile.write(record)` doesn't work because `TypeError: a bytes-like object is required, not 'str'`, so I have to add the `b` which is not working in the case of this variable. @Reinderien: I am using a `.txt` file because it's just to test, I will use another database later. – Camille BOUQUET Jul 21 '21 at 13:49
  • 2
    @Reinderien You should *never* attempt to guess on what the OP's faulty indentation should be and correct it. Instead, ask the OP to correct her own code. – Booboo Jul 21 '21 at 13:55
  • OK, convert it to bytes: `self.wfile.write(bytes(record,'utf-8'))` – Scott Hunter Jul 21 '21 at 13:59
  • @Booboo I'm going off of https://codereview.meta.stackexchange.com/a/6124/25834 which describes this case fairly closely (though it's for a different site, its verbiage describes SE broadly). Is there a meta policy for SO specifically? – Reinderien Jul 21 '21 at 14:16
  • 1
    @Reinderien I don't know if there is a formal policy. What I do know is that I was *severely* criticized for having done the same thing and I saw immediately the point of that criticism. When the indentation is clearly wrong, we all know something is amiss and we can, if we wish, use our wits to guess what the code is supposed to be. But if we "correct" the code erroneously, then we have done the OP (and everyone else) a great harm. Besides, it really is the OP's responsibility to post correctly. – Booboo Jul 21 '21 at 14:34

2 Answers2

1

The solution is to split the .txt file (variable data) and then to encode it:

#!/usr/bin/python
from http.server import BaseHTTPRequestHandler,HTTPServer

class myHandler(BaseHTTPRequestHandler):
    def do_GET(self):

         ###############################

         File = open('data1.txt',"r")
         if(File == None):
             print("File Not Found..")
         else:
             while(True):
                 # extracting data from records 
                 record = File.readline()
                 print(record.encode())
                 if (record == ''): break
                 data = record.split()
                 print("data:",data[0].encode())

         File.close()

         ###############################


         self.send_response(200)
         self.send_header('Content-type','text/html')
         self.end_headers()
         self.wfile.write(
        "<h1>".encode() + data[0].encode() + "</h1>".encode())
         return

try:
    server = HTTPServer(('localhost', 8080), myHandler)
    print ('HTTPServer started')
    server.serve_forever()

except KeyboardInterrupt:
    print ('server.socket.close()')
    server.socket.close()

Thank you for your help!

Camille BOUQUET
  • 445
  • 1
  • 6
  • 18
0

First note that the documentation recommends against this approach:

Warning: http.server is not recommended for production. It only implements basic security checks.

Something like Flask is just as easy, and a little more typical for production use. Anyway, continuing with your use of http.server:

  • You're not actually serving text content; you're serving HTML content, so rename your .txt file to .html
  • Consider using a different handler, namely SimpleHTTPRequestHandler, that serves content from the filesystem directly
  • Move your Hello (etc.) to the .html

You've also misconstrued how file operations work in Python when the file is not found. This is not going to work:

        if(File == None):
            print("File Not Found..")

because on failure, open does not return None; it raises an exception.

For your record reference the fix should be just

self.wfile.write(record.encode())

You also need to drop your read-loop; currently this:

if (record == ''): break

is guaranteeing that your shown record will be a blank string. Instead, just do a single file.read() and show the works, rather than reading line by line.

Reinderien
  • 11,755
  • 5
  • 49
  • 77
  • 1
    Thank you for your answer, I added these changes. But you didn't help me on my real problem which is still how to call the variable `record` with `self.wfile.write()`. – Camille BOUQUET Jul 21 '21 at 14:14
  • Refer to the edit; `encode` is the right thing to call here. But even then, you shouldn't need to do any of this if you just serve off of the filesystem via `SimpleHTTPRequestHandler`. – Reinderien Jul 21 '21 at 14:18
  • I tried the two solutions and in both cases, the reference is never displayed... – Camille BOUQUET Jul 21 '21 at 14:22
  • OK? Do you see any error messages? What specifically is displayed? Does the browser load the response at all? – Reinderien Jul 21 '21 at 14:27
  • No I don\t have any error `HTTPServer started 127.0.0.1 - - [21/Jul/2021 16:31:04] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [21/Jul/2021 16:31:04] "GET /favicon.ico HTTP/1.1" 200 -` and the browser displays all the contents I have in `self.wfile.write()` except `self.wfile.write(record.encode())` – Camille BOUQUET Jul 21 '21 at 14:32
  • What is the size in bytes of your text file? – Reinderien Jul 21 '21 at 14:33