web server using HTTPServer

build a web server

protocols

TCP (transimission control protocol): 服务端将信息分成packages,通过网络与客户端进行传播。当一个包丢失后,服务端可以重新发送。

UDP: User Datagram Protocol更适用于传输流媒体的信息(audio & video)

DNS: domain name service. 用户输入www.baidu.com后,dns帮助转化网址为对应的ip地址。

web server using HTTPServer_第1张图片

http

web server using HTTPServer_第2张图片
get 和 post属于比较常用的方式
get: 客户端想要从服务器下载资源: 读操作
post: 客户端想要更改服务器中的一些信息: update, delete, insert (当然也可以read)

服务端对于客户端的请求予以回应:已状态码(status code)的方式进行回应
web server using HTTPServer_第3张图片
以下为python3代码:


from http.server import BaseHTTPRequestHandler, HTTPServer


class WebServerHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        if self.path.endswith("/hello"):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            message = b""
            message += b"Hello!"
            self.wfile.write(message)
            print(message)
            return
        else:
            self.send_error(404, 'File Not Found: %s' % self.path)


def main():
    try:
        port = 8080
        server = HTTPServer(('', port), WebServerHandler)
        print("Web Server running on port %s" % port)
        server.serve_forever()
    except KeyboardInterrupt: # ctr-Z
        print(" ^C entered, stopping web server....")
        server.socket.close()

if __name__ == '__main__':
    main()

web server using HTTPServer_第4张图片
python 3.9 post 方式


from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi

class WebServerHandler(BaseHTTPRequestHandler):

    def do_GET(self):
    
        if self.path.endswith("/hello"):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            message = b""
            message += b"Hello!"
            message += b"

what would you like to say?

"
message += b"" self.wfile.write(message) print(message) return else: self.send_error(404, 'File Not Found: %s' % self.path) def do_POST(self): self.send_response(301) #self.send_header('Content-type', 'text/html') self.end_headers() print('2----------------') print(self.headers) print(self.headers.__dict__) ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) message_content = fields.get('message') print(message_content) output = b"

OK,how about this:

"
output += ("

%s

"
% message_content[0]).encode('ascii') print('2----------------') output += b"

what would you like to say?

"
output += b'' self.wfile.write(output) print('3----------------') print(message) return def main(): try: port = 8080 server = HTTPServer(('', port), WebServerHandler) print("Web Server running on port %s" % port) server.serve_forever() except KeyboardInterrupt: # ctr-Z print(" ^C entered, stopping web server....") server.socket.close() if __name__ == '__main__': main()

web server using HTTPServer_第5张图片


from http.server import BaseHTTPRequestHandler, HTTPServer
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
import cgi

Base = declarative_base()

class Restaurant(Base):
    __tablename__ = 'restaurant'
    id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)

class MenuItem(Base):
    __tablename__ = 'menu_item'
    name =Column(String(80), nullable = False)
    id = Column(Integer, primary_key = True)
    description = Column(String(250))
    price = Column(String(8))
    course = Column(String(250))
    restaurant_id = Column(Integer,ForeignKey('restaurant.id'))
    restaurant = relationship(Restaurant) 

#We added this serialize function to be able to send JSON objects in a serializable format
    @property
    def serialize(self):
        return {'name'         : self.name,
                'description'  : self.description,
                'id'           : self.id,
                'price'        : self.price,
                'course'       : self.course}
 
engine = create_engine('sqlite:///restaurantmenu.db')
# Bind the engine to the metadata of the Base class so that the
# declaratives can be accessed through a DBSession instance
Base.metadata.bind = engine

DBSession = sessionmaker(bind=engine)
# A DBSession() instance establishes all conversations with the database
# and represents a "staging zone" for all the objects loaded into the
# database session object. Any change made against the objects in the
# session won't be persisted into the database until you call
# session.commit(). If you're not happy about the changes, you can
# revert all of them back to the last commit by calling
# session.rollback()
session = DBSession()

class WebServerHandler(BaseHTTPRequestHandler):

    def do_GET(self):
    
        if self.path.endswith("/hello"):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            message = b""
            message += b"Hello!"
            message += b"

what would you like to say?

"
message += b"" self.wfile.write(message) print(message) return elif self.path.endswith('/restaurants'): print(self.path) self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() msg_list = ["

Create a new Restaurant

Hello! All restaurants are listed below:

"
] restaurants = session.query(Restaurant).all() for rstrnt in restaurants: msg_list.append('
'
) msg_list.append('------------------------------') msg_list.append('

{}

'
.format(rstrnt.name)) msg_list.append("Edit".format(rstrnt.id)) msg_list.append(" ") msg_list.append("Delete".format(rstrnt.id)) msg_list.append('
'
) msg_list.append('------------------------------') msg_list.append('') msg = ''.join(msg_list).encode('ascii') self.wfile.write(msg) print(msg) return elif self.path.endswith('/restaurants/new'): print(self.path) self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() msg_list = ['

Hello! Please enter the name of the restaurant you wanna add:

'
] msg_list.append("
"
) msg_list.append("") msg = ''.join(msg_list).encode('ascii') self.wfile.write(msg) print(msg) return elif self.path.endswith('/edit'): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() vals = self.path.split('/') try: restaurant_id = int(vals[-2]) restaurant = session.query(Restaurant).filter_by(id=restaurant_id).first() restaurant_name = restaurant.name except: self.wfile.write(b"you come to a wrong page") return msg_list = ['

Hello! Please change type the new name of Restaurant {}:

'
.format(restaurant_name)] msg_list.append("
"
.format(restaurant.id)) self.wfile.write("".join(msg_list).encode('ascii')) return elif self.path.endswith("/delete"): restaurantIDPath = self.path.split("/")[2] myRestaurantQuery = session.query(Restaurant).filter_by( id=restaurantIDPath).one() if myRestaurantQuery: self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() output = "" output += "" output += "

Are you sure you want to delete %s?" % myRestaurantQuery.name output += "
" % restaurantIDPath output += "" output += ""
output += "" self.wfile.write(output.encode('ascii')) else: self.send_error(404, 'File Not Found: %s' % self.path) def do_POST(self): if self.path.endswith('/restaurants/new'): ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) restaurant_name_list = fields.get('restaurantName') restaurant = Restaurant(name=restaurant_name_list[0]) session.add(restaurant) session.commit() self.send_response(301) self.send_header('Content-type', 'text/html') self.send_header('Location', '/restaurants') # 跳转目标地址 self.end_headers() return elif self.path.endswith('/edit'): ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) restaurant_name_list = fields.get('restaurantName') vals = self.path.split('/') try: restaurant_id = int(vals[-2]) restaurant = session.query(Restaurant).filter_by(id=restaurant_id).first() restaurant.name = restaurant_name_list[0] session.add(restaurant) session.commit() except: self.wfile.write(b"you come to a wrong page") return self.send_response(301) self.send_header('Content-type', 'text/html') self.send_header('Location', '/restaurants') # 跳转目标地址 self.end_headers() return elif self.path.endswith("/delete"): restaurantIDPath = self.path.split("/")[2] myRestaurantQuery = session.query(Restaurant).filter_by(id=restaurantIDPath).first() if myRestaurantQuery: session.delete(myRestaurantQuery) session.commit() self.send_response(301) self.send_header('Content-type', 'text/html') self.send_header('Location', '/restaurants') self.end_headers() return elif self.path.endswith('/hello'): self.send_response(301) #self.send_header('Content-type', 'text/html') self.end_headers() print('2----------------') print(self.headers) print(self.headers.__dict__) ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) message_content = fields.get('message') print(message_content) output = b"

OK,how about this:

"
output += ("

%s

"
% message_content[0]).encode('ascii') print('2----------------') output += b"

what would you like to say?

"
output += b'' self.wfile.write(output) print('3----------------') print(output) return def main(): try: port = 8080 server = HTTPServer(('', port), WebServerHandler) print("Web Server running on port %s" % port) server.serve_forever() except KeyboardInterrupt: # ctr-Z print(" ^C entered, stopping web server....") server.socket.close() if __name__ == '__main__': main()


from http.server import BaseHTTPRequestHandler, HTTPServer
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
import cgi

Base = declarative_base()

class Restaurant(Base):
    __tablename__ = 'restaurant'
    id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)

class MenuItem(Base):
    __tablename__ = 'menu_item'
    name =Column(String(80), nullable = False)
    id = Column(Integer, primary_key = True)
    description = Column(String(250))
    price = Column(String(8))
    course = Column(String(250))
    restaurant_id = Column(Integer,ForeignKey('restaurant.id'))
    restaurant = relationship(Restaurant) 

#We added this serialize function to be able to send JSON objects in a serializable format
    @property
    def serialize(self):
        return {'name'         : self.name,
                'description'  : self.description,
                'id'           : self.id,
                'price'        : self.price,
                'course'       : self.course}
 
engine = create_engine('sqlite:///restaurantmenu.db')
# Bind the engine to the metadata of the Base class so that the
# declaratives can be accessed through a DBSession instance
Base.metadata.bind = engine

DBSession = sessionmaker(bind=engine)
# A DBSession() instance establishes all conversations with the database
# and represents a "staging zone" for all the objects loaded into the
# database session object. Any change made against the objects in the
# session won't be persisted into the database until you call
# session.commit(). If you're not happy about the changes, you can
# revert all of them back to the last commit by calling
# session.rollback()
session = DBSession()

class WebServerHandler(BaseHTTPRequestHandler):

    def do_GET(self):
    
        if self.path.endswith("/hello"):
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            message = b""
            message += b"Hello!"
            message += b"

what would you like to say?

"
message += b"" self.wfile.write(message) print(message) return elif self.path.endswith('/restaurants'): print(self.path) self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() msg_list = ["

Create a new Restaurant

Hello! All restaurants are listed below:

"
] restaurants = session.query(Restaurant).all() for rstrnt in restaurants: msg_list.append('
'
) msg_list.append('------------------------------') msg_list.append('

{}

'
.format(rstrnt.name)) msg_list.append("Edit".format(rstrnt.id)) msg_list.append(" ") msg_list.append("Delete".format(rstrnt.id)) msg_list.append('
'
) msg_list.append('------------------------------') msg_list.append('') msg = ''.join(msg_list).encode('ascii') self.wfile.write(msg) print(msg) return elif self.path.endswith('/restaurants/new'): print(self.path) self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() msg_list = ['

Hello! Please enter the name of the restaurant you wanna add:

'
] msg_list.append("
"
) msg_list.append("") msg = ''.join(msg_list).encode('ascii') self.wfile.write(msg) print(msg) return elif self.path.endswith('/edit'): self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() vals = self.path.split('/') try: restaurant_id = int(vals[-2]) restaurant = session.query(Restaurant).filter_by(id=restaurant_id).first() restaurant_name = restaurant.name except: self.wfile.write(b"you come to a wrong page") return msg_list = ['

Hello! Please change type the new name of Restaurant {}:

'
.format(restaurant_name)] msg_list.append("
"
.format(restaurant.id)) self.wfile.write("".join(msg_list).encode('ascii')) return elif self.path.endswith("/delete"): restaurantIDPath = self.path.split("/")[2] myRestaurantQuery = session.query(Restaurant).filter_by(id=restaurantIDPath).first() if myRestaurantQuery: self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() output = "" output += "" output += "

Are you sure you want to delete %s?" % myRestaurantQuery.name output += "
" % restaurantIDPath output += "" output += ""
output += "" self.wfile.write(output.encode('ascii')) else: self.wfile.write(b"you come to a wrong page") else: self.send_error(404, 'File Not Found: %s' % self.path) def do_POST(self): if self.path.endswith('/restaurants/new'): ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) restaurant_name_list = fields.get('restaurantName') restaurant = Restaurant(name=restaurant_name_list[0]) session.add(restaurant) session.commit() self.send_response(301) self.send_header('Content-type', 'text/html') self.send_header('Location', '/restaurants') # 跳转目标地址 self.end_headers() return elif self.path.endswith('/edit'): ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) restaurant_name_list = fields.get('restaurantName') vals = self.path.split('/') try: restaurant_id = int(vals[-2]) restaurant = session.query(Restaurant).filter_by(id=restaurant_id).first() restaurant.name = restaurant_name_list[0] session.add(restaurant) session.commit() except: self.wfile.write(b"you come to a wrong page") return self.send_response(301) self.send_header('Content-type', 'text/html') self.send_header('Location', '/restaurants') # 跳转目标地址 self.end_headers() return elif self.path.endswith("/delete"): restaurantIDPath = self.path.split("/")[2] myRestaurantQuery = session.query(Restaurant).filter_by(id=restaurantIDPath).first() if myRestaurantQuery: session.delete(myRestaurantQuery) session.commit() self.send_response(301) self.send_header('Content-type', 'text/html') self.send_header('Location', '/restaurants') self.end_headers() else: self.wfile.write(b"you come to a wrong page") self.send_response(301) self.send_header('Content-type', 'text/html') self.end_headers() return elif self.path.endswith('/hello'): self.send_response(301) #self.send_header('Content-type', 'text/html') self.end_headers() print('2----------------') print(self.headers) print(self.headers.__dict__) ctype, pdict = cgi.parse_header(self.headers.get('content-type')) if ctype == 'multipart/form-data': pdict['boundary'] = pdict['boundary'].encode('ascii') fields = cgi.parse_multipart(self.rfile, pdict) message_content = fields.get('message') print(message_content) output = b"

OK,how about this:

"
output += ("

%s

"
% message_content[0]).encode('ascii') print('2----------------') output += b"

what would you like to say?

"
output += b'' self.wfile.write(output) print('3----------------') print(output) return def main(): try: port = 8080 server = HTTPServer(('', port), WebServerHandler) print("Web Server running on port %s" % port) server.serve_forever() except KeyboardInterrupt: # ctr-Z print(" ^C entered, stopping web server....") server.socket.close() if __name__ == '__main__': main()

你可能感兴趣的:(web-development,python,python)