今天就让我们通过Flask快速完成并部署一个Restuful服务,不要轻易走开!1.框架概述我们先来看一下大致的代码框架。在这里说明一下,这套代码结构是参考经典的flask书《Flask Web Development》写的。如果你想要本书的电子版,请与我联系。二、代码详解1、依赖包放在需求文件中。flask==1.0.2flask-script==2.0.6flask-restful==0.3.7flask-sqlalchemy==2.3.3flask-httpauth==3.2.4itsdangerous==1.1.0Flask-SQLAlchemy==2.3.2psycopg2==2.7。6.12、配置文件在config.py文件中。导入osbasedir=os.path.abspath(os.path.dirname(__file__))类配置:@staticmethoddefinit_app(app):passclassDevelopmentConfig(Config):passclassTestingConfig(Config):TESTING=TrueSQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(basedir,'my.sqlite3')classProductionConfig(Config):SQLALCHEMY_DATABASE_URI=os.environ.get('DATABASE_URL')config={'development':DevelopmentConfig,'testing':测试配置,'production':ProductionConfig,'default':DevelopmentConfig}这里我使用简单易用的sqlite数据库,当然你也可以使用其他关系型数据库,比如MySQL。3.程序入口文件manage.pyfromappimportcreate_app,dbfromflask_scriptimportManager,Shell,Serverfromapp.modelsimportUser,AdminUser,Pictureapp=create_app('testing')manager=Manager(app)defmake_shell_context():returndict(app=app,db=db,User=User,AdminUser=AdminUser,Picture=Picture)manager.add_command("runserver",服务器(use_debugger=True,host='0.0.0.0',port='9980'))manager.add_command("shell",Shell(make_context=make_shell_context))if__name__=='__main__':manager.run(default_command='runserver')介绍flask的命令用法,主要用于数据库初始化和快速启动flask服务。4.蓝图介绍蓝图可以帮助我们实现模块化应用的功能。创建一个flaskapp,在主程序的__init__.py文件中注册模块。fromflaskimportFlaskfromflask_sqlalchemyimportSQLAlchemyfromconfigimportconfigdb=SQLAlchemy()defcreate_app(config_name):app=Flask(__name__)app.config.from_object(config[config_name])config[config_name].init_app(app)db.init_app(app)from.mainimportmainasmain_blueprintapp.register_blueprint(main_blueprint)from.api_1_0importapi_1_0asapi_blueprintapp.register_blueprint(api_blueprint)returnapp也引入了api模块__init__.py中的蓝图。从烧瓶导入Blueprintapi_1_0=Blueprint('api_1_0',__name__,url_prefix='/api')from.importapi_user,api_auth5,表模型在models.py文件中,定义了当前使用的数据库表结构。从。importdbfromwerkzeug.securityimportgenerate_password_hash,check_password_hashclassAdminUser(db.Model):__tablename__='adminuser'id=db.Column(db.Integer,primary_key=True)用户名??=db.Column(db.String(128),unique=True,index=True)password_hash=db.Column(db.String(128))@staticmethoddefinit_user():users=AdminUser.query.filter_by(username='admin').first()如果用户为None:用户=AdminUser(username='admin')users.password='hardtoguess'db.session.add(users)db.session.commit()@propertydefpassword(self):raiseAttributeError('密码不是可读属性')@password.setterdefpassword(self,password):self.password_hash=generate_password_hash(password)defverify_password(self,password):returncheck_password_hash(self.password_hash,password)def__repr__(self):return"<用户{}>“.格式(self.username)classUser(db.Model):__tablename__='users'id=db.Column(db.Integer,primary_key=True)username=db.Column(db.String(128),unique=True,index=True)picture_count=db.Column(db.Integer)class图片(db.Model):__tablename__='pictures'id=db.Column(db.Integer,primary_key=True)picture_id=db.Column(db.Integer,db.ForeignKey('users.id'))picture_name=db.Column(db.String(128))picture=db.Column(db.Text)其中AdminUser是API的认证用户的存在,会后面调用API的时候会用到user,而User和Picture就是后面需要操作的表。我们重点关注AdminUser类,它定义了一个静态方法init_user,用于后面初始化数据库。我们需要手动将这个认证用户添加到数据库中。方法verify_password用于后面API的认证。如果用户在数据库中的哈希值相同,则认证通过。6、API部分的api认证代码使用了flask_httpauth库。fromflask_httpauthimportHTTPBasicAuthfromflaskimportjsonifyfrom..modelsimportAdminUserauth=HTTPBasicAuth()@auth.error_handlerdefunauthorized():error_info='{}'.format("无效凭据")print(error_info)response({'er:error_info})response.status_code=403returnresponse@auth.verify_passworddefverify_password(username,password):user=AdminUser.query.filter_by(username=username).first()ifnotuserornotuser.verify_password(password):返回FalsereturnTrue先去数据库查询用户,如果没有不正确的hash值,则返回False,认证失败。7、设计API在api_user.py文件中,初始化flask_restful的Api类,用于后面添加资源。api_user=Api(api_1_0)classUserAddApi(Resource):@auth.login_requireddefpost(self):user_info=request.get_json()try:u=User(username=user_info['username'])p=Picture(picture_name=user_info['用户名'])u.password=user_info['密码']u.picture_count=user_info['picture_count']db.session.add(u)db.session.add(p)db.session.commit()except:logger.info("Useradd:{}failure...".format(user_info['username']))db.session.rollback()returnFalseelse:logger.info("Useradd:{}success...".format(user_info['username']))最后返回True:db.session.close()api_user.add_resource(UserAddApi,'/useradd',endpoint='useradd')这里只接受json请求消息Body,并相应更新数据库中表的值。3.初始化使用manage中定义的shell命令进入shell界面。执行db.create_all()创建模型中定义的表。执行成功后,查看数据库如下:表已经创建成功,但是我们的admin用户还不存在。继续执行命令AdminUser.init_user()插入Admin用户。至此,初始化工作就完成了。4、测试API执行命令pythonmanage.py启动flask服务,可以看到本地9980端口已经启动。使用postman工具测试useraddAPI,选择POST方式,使用BasicAuthas身份验证方法,并在正文中使用json形式。发送请求测试如下:name改成错误的值会认证失败。
