python全栈开发第四十四期(57挑战之53python实现客户端)
python全栈开发第四十四期(57挑战之53python实现客户端)上代码:https://www.toutiao.com/article/7089633631219663392/不废话,实现架构如下图:https://www.toutiao.com/article/7087364110660223522/https://www.toutiao.com/article/7091078001969922568/
希望这是最后一次写53题了。昨天下午花了2小时,完全重新盘了一遍。
不过写出来后,感觉稍微加深了一些对python处理http 的理解,也算没白弄。
介绍题目下:
红框里要求写一个安卓或者ios的app,直接连接到后端服务器,(自己写代码),实现创建API 来获取列表及存储文件。
不废话,实现架构如下图:
- 之前客户端已经做好了,参考文章:
https://www.toutiao.com/article/7087364110660223522/
- 服务端也已经做好,参考文章:
https://www.toutiao.com/article/7091078001969922568/
- redis 操作,参考文章
https://www.toutiao.com/article/7089633631219663392/
上代码:
客户端代码:clientside.py
from Flask import Flask render_template Request url_for redirect
from datetime import date
import requests
import json
import time
def getdate():
return date.today()
def post(url note):
timestring = time.strftime("%Y-%m-%d %H:%M:%S" time.localtime())
post_data = json.dumps({timestring:note})
req = requests.post(url json=post_data)
print(req.text)
app = Flask(__name__)
@app.route('/' methods=['GET' 'POST'])
@app.route('/index')
@app.route('/home')
def index():
if request.method == 'POST':
notes = request.form['notes']
url = 'http://127.0.0.1:8008'
post(url notes)
return render_template('display.HTML' info=notes)
if request.method == 'GET':
return render_template('index.html')
@app.route('/list' methods=['GET'])
def list():
r = requests.get("http://127.0.0.1:8008/list")
info2 = json.loads(r.text)
return render_template('showall.html' info2=info2)
if __name__ == '__main__':
app.run(host='0.0.0.0' port=80 debug = True)
服务端代码:webapi.py
from http.server import BaseHTTPRequesthandler HTTPServer
import json
import cgi
import serverside
from serverside import get_input judge_input insert_into_redis drop_redis display_redis
class Server(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type' 'application/json')
self.end_headers()
def do_HEAD(self):
self._set_headers()
# GET sends back a Hello world message
def do_GET(self):
self._set_headers()
message1 = json.dumps({'hello': 'world' 'received': 'ok'})
response1 = bytes(json.dumps(message1) 'utf-8')
self.wfile.write(response1)
d1=display_redis()
message2 = json.dumps(d1)
response2 = bytes(json.dumps(message2) 'utf-8')
self.wfile.write(response2)
# POST echoes the message adding a JSON field
def do_POST(self):
ctype pdict = cgi.parse_header(self.headers.get('content-type'))
# refuse to receive non-json content
if ctype != 'application/json':
self.send_response(400)
self.end_headers()
return
# read the message and convert it into a python dictionary
length = int(self.headers.get('content-length'))
message = json.loads(self.rfile.read(length))
print(message)
print(type(message))
dic=json.loads(message)
#print(message.values())
#print(list(message.values())[0])
values=list(dic.values())[0]
print(values)
print(type(values))
insert_into_redis(values)
#print(type(message.values()))
#print(message.keys())
#print(type(message.keys()))
# add a property to the object just to mess with data
#message['received'] = 'ok'
# send the message back
self._set_headers()
response = bytes(json.dumps(message) 'utf-8')
self.wfile.write(response)
def run(server_class=HTTPServer handler_class=Server port=8008):
server_address = ('' port)
httpd = server_class(server_address handler_class)
print('Starting httpd on port {0}...'.format(port))
httpd.serve_forever()
if __name__ == "__main__":
from sys import argv
if len(argv) == 2:
run(port=int(argv[1]))
else:
run()
服务端代码2:
"""
replace 方法支持替代一次,用下面的方案
replace() 方法
比如,输入的字符串为’one two one two one’,第一个参数为替换前的参数,第二个为替换后的参数。默认会替换字符串中的所有符合条件的字符串。
s = 'one two one two one'
print(s.replace(' ' '-'))
# one-two-one-two-one
1
2
3
4
也可以指定一个最大替换次数值,一旦指定,只会替换前面匹配的n个字符串。
print(s.replace('one' 'XXX'))
# XXX two XXX two XXX
print(s.replace('one' 'XXX' 2))
# XXX two XXX two one
————————————————
版权声明:本文为CSDN博主「独家雨天」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u013019701/article/details/104056898
"""
import redis
from redis import StrictRedis ConnectionPool
import re
import json
import time
def get_input():
# 输入键盘数据,返回键盘的输入数据
instructions = """
Please provide a task which you want input,
if you wanna write a task with the format like this:
new notes go to school today
if you wanna list the task with the format like this:
list notes
if you wanna delete some note you can use list task to check the notes id
then use this command to delete the note
delete note id 1
if you wanna stop writing
just enter a blank then the loop will not continue
"""
print(instructions)
values = input("Please provide the information")
return values
def judge_input(values):
# 判断获取到的字符串的含义,如果是插入则插入,如果是删除则删除,如果是显示,则显示,如果是空白则退出循环
if re.match("new notes" values) != None:
hanyi = 0
value = values.replace("new notes " '' 1)
if re.match("list notes" values) != None:
hanyi = 2
value = values.replace("list notes " '' 1)
if re.match("delete note id" values) != None:
hanyi = 1
value = values.replace("delete note id " '' 1)
if re.match(" " values) != None:
hanyi = 3
value = " "
return hanyi value
def insert_into_redis(value):
# 如果含义为插入,则做插入操作
pool = ConnectionPool(host='localhost' port=6379 db=0 decode_responses=True)
# redis 取出的结果默认是字节,我们可以设定 decode_responses=True 改成字符串。
r = StrictRedis(connection_pool=pool)
if r.hkeys('note') == []:
id = 1
else:
id = int(max(r.hkeys('note'))) 1
string = time.strftime("%Y-%m-%d %H:%M:%S" time.localtime())
r.hset("note" id json.dumps({"date": string "content": value}))
print("The value {0} is inserted".format(value))
def drop_redis(value):
# 如果含义是删除,则做删除操作
pool = ConnectionPool(host='localhost' port=6379 db=0 decode_responses=True)
r = StrictRedis(connection_pool=pool)
r.hdel('note' value)
print("the date {} has been removed".format(value))
def display_redis():
# 如果含义是展示,则做展示
print("** displayed")
pool = ConnectionPool(host='localhost' port=6379 db=0 decode_responses=True)
r = StrictRedis(connection_pool=pool)
d1 = {}
for k in r.hkeys('note'):
print("id is {0}: ".format(k) end="")
d = r.hget('note' k) #d是一个字符串
d1.update({k:d}) #制作一个字典,key 是id, value 是字符串
#print(type(json.loads(d))) #debug 用,这里可以看到返回的类型是字典
#print(type(d)) #debug 用,这里可以看到返回的类型是字符串
print(json.loads(d))
for values in d1.values(): #debug 用
print(values) #debug 用,展示所有value 的信息
print(d1) #debug 用,展示所有字典的信息
return d1
if __name__ == "__main__":
while 1:
values = get_input()
hanyi notes = judge_input(values)
if hanyi == 0:
# 如果是插入,则做插入操作
insert_into_redis(notes)
if hanyi == 1:
# 如果是删除,则做删除操作
drop_redis(notes)
if hanyi == 2:
# 如果是展示,则做展示操作
display_redis()
if hanyi == 3:
# 如果含义是退出,则跳出循环
break
客户端的几个HTML ,很简单
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>57-53</title>
</head>
<body>
<form method = "post">
<label for="name">please provide the note which you wanna input</label>
<input type="text" name="notes" required><br>
<input type="submit" name="submit" value="记录">
</form>
</body>
</html>
showall.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>57-53</title>
</head>
<body>
{{info2}}
</body>
</html>
display.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>57-53</title>
</head>
<body>
{{info}}
</body>
</html>
效果图:
登录html 后插入:前端截图
后端的截图:
从数据库里面可以查到这条信息
直接list 8008服务端是能看到所有数据了。
明天把list 问题解决后补在本文档。
留一个作业 list的时候报错了。
--added next day
在昨天的基础上做一下debug,从下文可以查到,response 相关信息的内容:
参考https://blog.csdn.net/qq_39208536/article/details/107881396
可以看到,返回是一个response 格式,utf-8 编码,
可以用命令r.content.decode('utf-8') 对它解码。
可以用命令r.json() 对内容做反序列化,昨天反序列化失败的原因是,在服务端代码里面一次返回了两个消息,因此处理失败。我把服务端确认的那端代码直接干掉,问题解决。
客户端(80) list 的效果截图
客户端python 进程返回结果(蓝框)
clientside.py 截图
服务端返回值:
webapi.py截图