当前位置:首页 >焦点 >从头完成一个 Restful API 服务 完成务不要轻易走开哦

从头完成一个 Restful API 服务 完成务不要轻易走开哦

2024-06-30 21:53:51 [百科] 来源:避面尹邢网

从头完成一个 Restful API 服务

作者:萝卜大杂烩 数据库 其他数据库 着重说下 AdminUser 类,完成务定义了一个静态方法 init_user,完成务是完成务用来后面初始化数据库的,我们需要把这个鉴权用户手动添加到数据库中。完成务方法 verify_password 用于后面 API 的完成务鉴权,如果数据库存在该用户且密码的完成务哈希值相同,则鉴权通过。完成务

今天一起来通过 Flask 快速完成并部署一个 Restuful 服务,完成务不要轻易走开哦!完成务

一、完成务框架概要

先来看看大致的完成务代码框架。

从头完成一个 Restful API 服务 完成务不要轻易走开哦

图片

从头完成一个 Restful API 服务 完成务不要轻易走开哦

这里说明下,完成务这套代码结构是完成务参照经典flask书籍《Flask Web Development》来写的,想要这本书电子版的完成务,可以联系我哈。完成务

从头完成一个 Restful API 服务 完成务不要轻易走开哦

二、代码详解

1,依赖包

放到了requirements文件里。

flask==1.0.2
flask-script==2.0.6
flask-restful==0.3.7
flask-sqlalchemy==2.3.3
flask-httpauth==3.2.4
itsdangerous==1.1.0
Flask-SQLAlchemy==2.3.2
psycopg2==2.7.6.1

2,配置文件

在config.py文件里。

import os


basedir = os.path.abspath(os.path.dirname(__file__))


class Config:

@staticmethod
def init_app(app):
pass
class DevelopmentConfig(Config):
pass
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'my.sqlite3')


class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')


config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}

这里我使用了简单易用的 sqlite 数据库,当然也可以使用其他关系型数据库,比如 MySQL 等。

3,程序入口文件

manage.py

from app import create_app, db
from flask_script import Manager, Shell, Server
from app.models import User, AdminUser, Picture


app = create_app('testing')
manager = Manager(app)


def make_shell_context():
return dict(app=app, db=db, User=User, AdminUser=AdminUser, Picture=Picture)


manager.add_command("runserver", Server(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 的 command 用法,主要用来做数据库的初始化操作和快速启动 flask 服务。

4,引入蓝图

蓝图可以帮我们实现模块化应用的功能。

在主程序的__init__.py文件中创建 flask app 并注册模块。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config

db = SQLAlchemy()


def create_app(config_name):
app = Flask(__name__)
app.config.from_object(config[config_name])
config[config_name].init_app(app)
db.init_app(app)

from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
from .api_1_0 import api_1_0 as api_blueprint
app.register_blueprint(api_blueprint)

return app

同时在 api 模块的__init__.py里引入蓝图。

from flask import Blueprint

api_1_0 = Blueprint('api_1_0', __name__, url_prefix='/api')
from . import api_user, api_auth

5,表模型

在models.py文件里,定义了当前用到的数据库表结构。

from . import db
from werkzeug.security import generate_password_hash, check_password_hash


class AdminUser(db.Model):
__tablename__ = 'adminuser'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), unique=True, index=True)
password_hash = db.Column(db.String(128))

@staticmethod
def init_user():
users = AdminUser.query.filter_by(username='admin').first()
if users is None:
users = AdminUser(username='admin')
users.password = 'hardtoguess'
db.session.add(users)
db.session.commit()

@property
def password(self):
raise AttributeError('password is not readable attribute')

@password.setter
def password(self, password):
self.password_hash = generate_password_hash(password)

def verify_password(self, password):
return check_password_hash(self.password_hash, password)

def __repr__(self):
return "<Users { }>".format(self.username)


class User(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 Picture(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 和 Picture 则是后面需要操作的表了。

着重说下 AdminUser 类,定义了一个静态方法 init_user,是用来后面初始化数据库的,我们需要把这个鉴权用户手动添加到数据库中。方法 verify_password 用于后面 API 的鉴权,如果数据库存在该用户的哈希值相同,则鉴权通过。

6,API部分

api 鉴权代码,使用 flask_httpauth 库。

from flask_httpauth import HTTPBasicAuth
from flask import jsonify
from ..models import AdminUser


auth = HTTPBasicAuth()


@auth.error_handler
def unauthorized():
error_info = '{ }'.format("Invalid credentials")
print(error_info)
response = jsonify({ 'error': error_info})
response.status_code = 403
return response


@auth.verify_password
def verify_password(username, password):
user = AdminUser.query.filter_by(username=username).first()
if not user or not user.verify_password(password):
return False
return True

先到数据库查询用户,如果不存在哈希值不正确,则返回 False,鉴权失败。

7,设计API

在api_user.py文件中,初始化 flask_restful 的 Api 类,用于后面添加 resource。

api_user = Api(api_1_0)


class UserAddApi(Resource):
@auth.login_required
def post(self):
user_info = request.get_json()
try:
u = User(username=user_info['username'])
p = Picture(picture_name=user_info['username'])
u.password = user_info['password']
u.picture_count = user_info['picture_count']
db.session.add(u)
db.session.add(p)
db.session.commit()
except:
logger.info("User add: { } failure...".format(user_info['username']))
db.session.rollback()
return False
else:
logger.info("User add: { } success...".format(user_info['username']))
return True
finally:
db.session.close()
api_user.add_resource(UserAddApi, '/useradd', endpoint='useradd')

这里只接受 json 的请求消息体,并且对应的更新数据库中表的值。

三、初始化

使用在 manage 中定义的 shell 命令,进入 shell 界面。

图片

执行 db.create_all() 创建在 models 中定义的表,执行成功之后,查看数据库如下:

图片

表已经创建成功,但是我们的 admin 用户还不存在,继续执行命令 AdminUser.init_user(),插入 Admin 用户。

图片

到此,初始化工作完毕。

四、测试API

执行命令 python manage.py 启动 flask 服务,可以看到已经在本地的9980端口启动。

图片

使用 postman 工具测试 useraddAPI,选择 POST 方式,鉴权方式使用 Basic Auth,body 中使用 json 形式。

图片

发送请求测试如下:

图片

如果修改名字为错误值,都会鉴权失败。

图片

责任编辑:武晓燕 来源: 萝卜大杂烩 AdminUser数据库鉴权

(责任编辑:知识)

    推荐文章
    热点阅读