在这次课堂中,有学习开发简单的接口。
首先需要根据代码所实现的功能和代表的含义将其分在不同的文件夹中。
一个完整的实现功能的文件夹,包含bin、config、data、lib、logs这四个文件夹和注意事项文件。bin目录下放启动文件,config文件夹下放设置文件、lib下放置了常用工具等等。接下来以两个简单的接口开发来看看整个文件的构成。
这两个接口分别是注册接口(需要判断账号是否已经存在)和登录接口(需要判断账号是否已经登录)。首先数据肯定是会存放在数据库中的,sql或者redis,那么在存取读写数据时必然会链接数据库,所以链接数据库是必须存在的。而自己开发接口,也是需要配置端口号的,这也是一个基础数据。
所以我们可以在config文件夹下的setting文件中,配置好数据库和一些固定的的基础数据。
1 # 数据库的配置信息 2 MYSQL_INFO = { 3 'host': '***.**.*.**', 4 'user': '***', 5 'passwd': '******', 6 'db': '***', 7 'charset': 'utf8', 8 'port': 3306 9 } 10 11 # Redis的配置信息 12 REDIS_INFO = { 13 'host': '***.**.*.**', 14 'password': '********', 15 'port': 6379, 16 'db': 7 # 第几个数据库 17 } 18 19 SERVER_PORT = 8989 # 接口服务的端口号
而后,在接口中,我们可能会经常使用到一些功能,比如执行sql语句,存储数据,读取数据等,而且注册接口可能涉及到密码加密等等。这类功能是常用的,可以将其定义为函数,方便调用。这些功能性代码可以放在lib文件夹下的tools文件中。
1 import hashlib 2 import pymysql 3 import redis 4 from config.setting import MYSQL_INFO, REDIS_INFO 5 6 7 def my_db(sql): 8 coon = pymysql.connect(**MYSQL_INFO) # 链接数据库,MYSQL_INFO本身就定义成了字典的,所以这边传入后会自动调整数据 9 # 调整为key = value的格式 10 cur = coon.cursor() # 建立游标 11 cur.execute(sql) # 执行sql语句 12 if sql.strip()[:6].upper() == 'SELECT': # 判断sql语句是否是单纯的查询语句 13 res = cur.fetchall() 14 else: 15 coon.commit() 16 res = cur.fetchall() 17 cur.close() # 关闭游标 18 coon.close() # 关闭链接 19 return res 20 21 22 def op_redis(k, v=None, time=None): 23 r = redis.Redis(**REDIS_INFO) # 链接redis数据库 24 if v: # 判断是否有value输入 25 if time: # 判断是否有时效时间输入 26 r.setex(k, v, time) 27 res = 'ok' 28 else: 29 r.set(k, v) 30 res = 'ok' 31 else: 32 res = r.get(k) 33 if res: 34 res = res.decode() 35 else: 36 pass 37 return res 38 39 40 def my_md5(s): 41 m = hashlib.md5() 42 m.update(s.encode()) 43 return m.hexdigest()
基础数据配置完毕后,就要开始写接口逻辑代码了。这些代码可以放在lib文件夹下的interface文件下。开发接口前需要先导入可能使用到的模块,然后将该文件定义为一个服务。接下来分析注册接口需求。首先我们需要定义该接口的请求方式,然后获取用户输入的账号密码,并判断该账号在数据库中是否存在,如果存在返回信息应该提示该账号已注册,如果不存在则可以顺利注册,需要将账号密码存入数据库中。此处数据都是存在redis数据库中的,所以调用了tools文件下的op_redis函数;密码是需要加密的,所以调用了my_md5函数。
1 import flask 2 import json 3 from lib.tools import my_md5,op_redis 4 import time 5 # 导入一些必须的模块,还有tools文件下已定义的的函数 6 7 8 server = flask.Flask(__name__) # __name__代表当前这个python文件,把当前这个python文件当做一个服务 9 10 11 @server.route('/reg', methods=['post']) 12 # 一个装置器,将函数变成一个接口 13 def register(): 14 username = flask.request.values.get('username') 15 passwd = flask.request.values.get('passwd') 16 if username and passwd: 17 info = op_redis('user_info_gyx:%s' % username) 18 if info: 19 res = {'msg': '该账号已存在', 'msg_code': 1001} 20 else: 21 op_redis('user_info_gyx:%s' % username, my_md5(passwd)) 22 res = {'msg': '注册成功', 'msg_code': 0} 23 else: 24 res = {'msg': '缺失必填数据', 'msg_code': 2001} 25 return json.dumps(res, ensure_ascii=False)
然后开发登录接口,首先获取用户的账号和密码,然后判断该账号是否已经登录,如果没有登录或者登录已失效则在数据库中存入登录信息和失效时间。所以我们可以根据检索该账号的登录信息来判断是否该账号已经登录了。登录信息中的key是账号的MD5数据,value是登录的时间。
1 @server.route('/log', methods=['post']) 2 def login(): 3 username = flask.request.values.get('username') 4 passwd = flask.request.values.get('passwd') 5 if username and passwd: 6 info = op_redis('user_info_gyx:%s' % username) # 判断该账号是否已经注册,注册接口记录的key=username,value=md5(pwd) 7 if info == my_md5(passwd): # 判断密码是否和注册账号记录的密码一致 8 lg_time = op_redis('user_info_gyx:%s' % my_md5(username)) # 判断该数据是否已经登录 9 if lg_time: # redis中该key还未失效,说明登录中 10 res = {'msg': '账号已登录', 11 'msg_code': 3001, 12 'logname': my_md5(username), 13 'time': lg_time} 14 else: # 无法获取到value说明没有登录或登录已失效,存储sessionid和失效时间 15 op_redis('user_info_gyx:%s' % my_md5(username), time.time(), 600) 16 res = {'msg': '登录成功', 17 'msg_code': 0, 18 'logname': my_md5(username), 19 'time': time.time()} 20 else: 21 res = {'msg': '密码错误', 'msg_code': 2001} 22 else: 23 res = {'msg': '必填参数未填写请检查接口文档', 'msg_code': 1001} # 1001就表示必填字段未填 24 return json.dumps(res, ensure_ascii=False)
这些接口肯定是需要启动文件的,启动代码就放在bin文件夹下的start文件中。这样需要增加新的接口时只需要在interface文件中编写即可,不用像以前代码都在一个文件下那样每次都要更新一大批数据。
1 from lib.interface import server 2 from config.setting import SERVER_PORT 3 server.run( 4 host='0.0.0.0', # 这里用0.0.0.0,那么其他人只要和本人处于同一个局域网中都可以访问该接口,也可以直接用127.0.0.1访问接口 5 port=SERVER_PORT, 6 debug=True 7 )
这样一个完整的接口文件就完成了。接下来理一下,首先在setting文件中储存常用的配置信息,如数据库链接信息,常用端口号等;然后在tools文件中存入常用的方法和函数,此时就会调用到setting中的基础信息;然后在interface中储存主体代码,此时就会用到tools文件中的各种方法和函数;接下来在bin目录下放启动文件,启动interface中的主体代码即可。