1、mock接口:模拟一些接口。有一些有关联的接口,在别的接口没有开发好的时候,需要用这个接口,就可以写一个假接口,返回想要的结果来模拟这个接口。
2、知道服务端的开发逻辑,有助于测试;
3、比如不想让其他人看很多数据库中的数据,可以通过接口只返回一部分数据。
1、flask是一个轻量级的开发框架
name:代表当前这个python文件
server = flask.Flask(name) :把当前这个python文件,当做一个服务
2、一个无需传参数的get接口
其中,‘index’是接口的路径。
method如果不写,默认为get。如果需要支持多种,可以写成[‘get’,‘post’]
port是端口号,默认为5000。debug=True,这样改了代码之后,不需要重启服务,会自动重启。
先运行,然后就可以用127.0.0.1/8999/index访问这个接口了。
但是这样响应的数据中,中文会变成乱码,想显示中文,按照下图方法即可:
3、一个post接口
开发一个注册接口,请求参数为:username和passwd。如果数据库中有该用户,就返回用户已存在。如果该用户不存在,就在数据库插入一条数据,返回注册成功
下面的代码需要连接数据库,连接数据库部分省略了。
为了让其他人也可以访问这个接口,可以用如下方法:
host=0.0.0.0表示只要在同一个局域网,别人访问的时候,用你的ip就可以访问了。ip指的是电脑的ip。
假如电脑的ip是10.2.88.122,那么别人电脑访问10.2.88.122:8999/reg即可。
目录结构如下
主目录命名为my_api,可以根据实际情况命名
bin:可执行文件,即启动程序
config:配置文件
data:放置一些数据,如sql、入参等
lib:主逻辑
logs:log
readme:一些说明
我们把上面的代码分到各个目录里面
1、配置文件config-setting.py
存放一些常量,如数据库的信息,redis的信息,端口号等
2、lib目录下tools.py
tools文件里写了怎么操作sql和redis
倒入setting里的信息,需要把my_api加到环境变量里。
在my_api文件夹上右击,选择mark directory as ->Source Root
导入setting
如果常量太多,则可以直接from config import setting
使用时,setting.MYSQL_INFO。用setting加点的方法。
3、lib目录下interface.py
先从interface中导入server,从setting中导入端口号。
1、目录结构同上,其中操作tools.py如下
import redis,hashlib
# pycharm帮你加环境变量
# 在主目录 my_api单击右键,Mark dictionary as 选sources root
from config.setting import REDIS_INFO
def op_redis(k,v=None,time=None):
r = redis.Redis(**REDIS_INFO)
if v:
r.set(k,v,time)
res = 'ok'
else:
res = r.get(k)
if res:
res = res.decode()
return res
def my_md5(s):
md = hashlib.md5()
md.update(s.encode())
return md.hexdigest()
2、要求:(1)登录成功后,把cookie写入redis,其中key为 wind_session:username,value为session。 session生成规则是“username+当前时间(年月日时分秒格式)”组成的字符串进行md5加密(2)posts接口获取到要发表的文章的标题和内容,用session判断用户的登录状态,如果是登录状态,则文章可以发表,并写入redis。
分析:
(1)首先说登录接口,我们需要先生成session,然后存放到redis里。session按照要求,生成方式如下
写入redis直接调用tools里面的op_redis即可,过期时间这里是随便设置的6000s
还有一步就是cookie
完整的登录代码如下。这里主要是为了说明cookie,因此没有对登录进行复杂的校验。最后会有完整的代码和运行结果,如果看的云里雾里,可以先看下运行结果。
(2)posts接口,需要获取到cookie,然后和redis中存的进行对比,如果一致,说明是登录状态,可以发表文章。
获取cookie用下面的方法
我们可以打印出来,看一下cookie的格式,如下,是字典格式。因此取session时,按照字典取值的方法即可。
对我们有用的cookie是以wind_session为开头的,其他的cookie我们不用关注。因此我们只选出这部分,取出session值,和redis中对比。
步骤为:
A、if语句中,是我们取到的cookie,从中提取出用户名和session。
B、从redis中取出对应用户的session
C、两者对比
D、如果是登录状态,返回文章发表成功,并且把文章写入redis。
(3)完整代码
interface.py:
import flask,time,json
from lib import tools
from config import setting
server = flask.Flask(__name__)
@server.route('/login')
def login():
username = flask.request.values.get('username')
pwd = flask.request.values.get('pwd')
if username == 'wind' and pwd == '123456':
session_id = tools.my_md5(username+time.strftime('%Y%m%d%H%M%S'))
key = 'wind_session:%s'%username
tools.op_redis(key,session_id,6000)
res = {'session_id':session_id,'error_code':0,'msg':'登录成功','login_time':time.strftime('%Y%m%d%H%M%S')}#给用户返回的信息
json_res = json.dumps(res,ensure_ascii=False)#返回结果为json格式
res = flask.make_response(json_res) #cookie 构造成返回结果的对象
res.set_cookie(key,session_id,6000)#最后的数字是cookie的失效时间
return res
@server.route('/posts')
def posts():
print('all_cookies',flask.request.cookies) #字典形式
cookies = flask.request.cookies #获取到所有的cookie
username = '' #定义这两个变量是为了在没有传cookie时用的
session = ''
for cookie in cookies:
if cookie.startswith('wind_session'): #判断cookie以syz_session开头的话,取到它
username = cookie #或者username = key session = value
session = cookies.get(cookie) #调用接口时,用户传的session
redis_session = tools.op_redis(username) #从redis中获取的
if redis_session == session:#判断传过来的session和redis中存的一样
title = flask.request.values.get('title') #获取文章标题
content = flask.request.values.get('content') #获取文章内容
article_key = 'article:%s'%title #key以article开头
tools.op_redis(article_key,content) #把文章写入redis
res = {'msg':'文章发表成功!','code':0}
else:
res = {'msg':'用户未登录','code':2009}
# print('username:',username)
# print('session:',session)
return json.dumps(res,ensure_ascii=False)
运行结果:
1、login接口
框起来的,是本次运行的cookie
redis里如下
2、posts接口
redis中
以上接口开发时,我们调用自己写的方法,是通过先把new_api文件夹mark as source root。这样在pycharm运行是没问题的,但是如果我们把代码在其他设备上使用,或者直接用命令行启动,就会有问题。
直接在命令行运行如下,会发现很多模块是找不到的。
如果把new_api添加到环境变量,就可以运行。
方法一:直接把new_api的路径添加到环境变量,但是这种方法不灵活,一旦文件换了位置,或者换个设备,需要重新修改路径
方法二:自动获取路径,添加到环境变量
file:获取当前路径,这个路径分隔符是“/”,不能直接添加到环境变量
os.path.abspath(file):当前路径,分隔符是"",可以直接添加到环境变量
os.path.dirname():取上一级目录