从头完成一个 Restful API 服务

简介: 从头完成一个 Restful API 服务

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

01.框架概要

先来看看大致的代码框架

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

02.代码详解

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 的请求消息体,并且对应的更新数据库中表的值。

03.初始化

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

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

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

到此,初始化工作完毕

04.测试API

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

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

发送请求测试如下:

如果修改名字或者密码为错误值,都会鉴权失败

至此,我们的一个简易 Restful 服务就搭建完成了,喜欢就点个吧~

相关文章
|
1月前
|
人工智能 API 开发工具
GitHub官方开源MCP服务!GitHub MCP Server:无缝集成GitHub API,实现Git流程完全自动化
GitHub MCP Server是基于Model Context Protocol的服务器工具,提供与GitHub API的无缝集成,支持自动化处理问题、Pull Request和仓库管理等功能。
527 2
GitHub官方开源MCP服务!GitHub MCP Server:无缝集成GitHub API,实现Git流程完全自动化
|
1月前
|
人工智能 算法 安全
OpenRouter 推出百万 token 上下文 AI 模型!Quasar Alpha:提供完全免费的 API 服务,同时支持联网搜索和多模态交互
Quasar Alpha 是 OpenRouter 推出的预发布 AI 模型,具备百万级 token 上下文处理能力,在代码生成、指令遵循和低延迟响应方面表现卓越,同时支持联网搜索和多模态交互。
174 1
OpenRouter 推出百万 token 上下文 AI 模型!Quasar Alpha:提供完全免费的 API 服务,同时支持联网搜索和多模态交互
|
2月前
|
XML JSON API
Understanding RESTful API and Web Services: Key Differences and Use Cases
在现代软件开发中,RESTful API和Web服务均用于实现系统间通信,但各有特点。RESTful API遵循REST原则,主要使用HTTP/HTTPS协议,数据格式多为JSON或XML,适用于无状态通信;而Web服务包括SOAP和REST,常用于基于网络的API,采用标准化方法如WSDL或OpenAPI。理解两者区别有助于选择适合应用需求的解决方案,构建高效、可扩展的应用程序。
|
2月前
|
机器学习/深度学习 设计模式 API
Python 高级编程与实战:构建 RESTful API
本文深入探讨了使用 Python 构建 RESTful API 的方法,涵盖 Flask、Django REST Framework 和 FastAPI 三个主流框架。通过实战项目示例,详细讲解了如何处理 GET、POST 请求,并返回相应数据。学习这些技术将帮助你掌握构建高效、可靠的 Web API。
|
2月前
|
人工智能 缓存 程序员
大模型文生图服务API设计原来如此简单(1)
文生图大模型的API设计其实很简单!无论是Midjourney这样的商业产品,还是ComfyUI这样的开源工具,它们的核心API设计都遵循着相似的简单原则。
123 1
|
3月前
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
|
5月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
114 12
|
6月前
|
XML JSON 缓存
深入理解RESTful API设计原则与实践
在现代软件开发中,构建高效、可扩展的应用程序接口(API)是至关重要的。本文旨在探讨RESTful API的核心设计理念,包括其基于HTTP协议的特性,以及如何在实际应用中遵循这些原则来优化API设计。我们将通过具体示例和最佳实践,展示如何创建易于理解、维护且性能优良的RESTful服务,从而提升前后端分离架构下的开发效率和用户体验。
|
6月前
|
JSON 缓存 测试技术
构建高效RESTful API的后端实践指南####
本文将深入探讨如何设计并实现一个高效、可扩展且易于维护的RESTful API。不同于传统的摘要概述,本节将直接以行动指南的形式,列出构建RESTful API时必须遵循的核心原则与最佳实践,旨在为开发者提供一套直接可行的实施框架,快速提升API设计与开发能力。 ####
|
6月前
|
JSON API 开发者
深入理解RESTful API设计原则
在数字化时代,API已成为连接不同软件应用的桥梁。本文旨在探讨RESTful API设计的基本原则和最佳实践,帮助开发者构建高效、可扩展的网络服务接口。通过解析REST架构风格的核心概念,我们将了解如何设计易于理解和使用的API,同时保证其性能和安全性。