Python Flask高级编程之RESTFul API前后端分离(学习笔记)

Flask-RESTful是一个强大的Python库,用于构建RESTful APIs。它建立在Flask框架之上,提供了一套简单易用的工具,可以帮助你快速地创建API接口。Flask-RESTful遵循REST原则,支持常见的HTTP请求方法,如GET、POST、PUT和DELETE,并提供了验证、授权、分页等功能。

  • 理解API
  • 理解Restful API
  • 理解装饰器
  • 理解Flask框架
  • 使用Python Flask 实现Restful API

API的理解

API(application programming interfaces),即应用程序编程接口。API由服务器(Server)提供(服务器有各种各样的类型,一般我们浏览网页用到的是web server,即网络服务器),通过API,计算机可以读取、编辑网站数据,就像人类可以加载网页、提交信息等。通俗地,API可以理解为家用电器的插头,用户只提供插座,并执行将插头插入插座的行为,不需要考虑电器内部如何运作。从另外一个角度上讲API是一套协议,规定了与外界的沟通方式:如何发送请求和接受响应。

理解 RESTful API

RESTful API即满足RESTful风格设计的API,RESTful表示的是一种互联网软件架构(以网络为基础的应用软件的架构设计),如果一个架构符合REST原则,就称它为RESTful架构。RESTful架构的特点:

  1. 每一个URI代表一种资源;
  2. 客户端和服务器之间,传递这种资源的某种表现层;把"资源"具体呈现出来的形式,叫做它的"表现层"(Representation)。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。
  3. 客户端通过四个HTTP动词,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

       

        后端的RESTful API指的是在服务器端实现的符合RESTful架构风格的API,它用于提供数据和服务,并且通常被前端或其他服务端所调用。后端的RESTful API包括了资源的定义、URI的设计、HTTP方法的使用以及数据格式等内容。

        而前端的RESTful API通常是指在客户端(比如浏览器端、移动端应用)中调用后端RESTful API的方式和规范。前端的RESTful API通常是通过Ajax、Fetch API或者一些库(比如axios)来发起HTTP请求,按照RESTful规范与后端的API进行交互,包括发送GET、POST、PUT、DELETE等请求,处理返回的数据等。

设计 RESTful API

设计 RESTful API 需要遵循一定的规范和原则。下面是一些常见的设计原则:

  • • 使用名词来表示资源,比如 /users/articles 等。
  • • 使用 HTTP 方法来表示对资源的操作,比如 GET、POST、PUT、DELETE 等。
  • • 使用 URL 参数来传递附加信息,比如查询条件、分页信息等。
  • • 使用 HTTP 状态码来表示操作结果,比如 200 表示成功、201 表示创建成功、400 表示请求错误、404 表示资源不存在等。
  • • 使用 JSON 或 XML 格式来传输数据。

下面是一个简单的 RESTful API 设计示例:

GET /users        # 获取所有用户信息
GET /users/1      # 获取指定用户信息
POST /users       # 添加用户
PUT /users/1      # 修改指定用户信息
DELETE /users/1   # 删除指定用户

理解装饰器

为了理解装饰器,应该先做好三个方面的准备:

1. 理解对象

        通过变量和对象的关系理解对象,在python中,如果要使用一个变量,不需要提前进行声明,只需要在用的时候,给这个变量赋值即可。如 a=1,整数1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1;这边形象比喻一下:这个过程就相当于“放风筝”,变量a就是你手里面的“线”,python就跟那根“线”一样,通过引用来接触和拴住天空中的风筝——对象。由于Python一切皆是对象的理念,所以函数也是一个对象。

比如,写一个函数,也可以是说创造了一个函数对象。

def cal(x,y):result=x+yreturn result

这时便是创造了一个叫做cal的函数对象。然后就可以使用了

cal(1,2)  #直接使用了cal这个函数对象
...........或者.............
calculate=cal  #把一个名为calculate的变量指向cal这个函数对象
calculate(1,2)
2.理解函数带括弧和不带括弧时分别代表的意思

        如果只写一个cal(不带扩号),此时的cal仅仅是代表一个函数对象;当写成cal(1,2)时,就是在告诉编辑器说“执行cal这个cal函数”

3.理解可变参数和关键字参数
  • 可变参数

        定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。如下,在函数内部,参数numbers接收到的是一个tuple,并且,调用该函数时,可以传入任意个参数,包括0个参数:

def calc(*numbers):sum = 0for n in numbers:sum = sum + n * nreturn sum
calc(1,2) # 5
  • 关键字参数

        可变参数允许传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。请看示例:

def person(name, age, **kw):print('name:', name, 'age:', age, 'other:', kw)>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

现在正式开始理解装饰器了。首先理解为什么需要装饰器呢?

        主要原因是装饰器可以起到一个“偷懒”的作用,比如写了很多个简单的函数,现在想知道在运行的时候是哪些函数在执行,并且你又觉得这个没有必要写测试,只是想要很简单的在执行完毕之前给它打印上一句“Start”,那该怎么办呢?你可以这样:

def func_name(arg):print 'Start func_name'sentence

想想看给每一个函数后面都加上那一句话将是非常的麻烦的。但是有了装饰器就不一样了。

def log(func):def wrapper(*arg, **kw):print 'Start%s'%funcreturn func(*arg,**kw)return wrapper@log
def func_a(arg):pass@log
def func_b(arg):pass@log
def func_c(arg):pass

这段代码是一个简单的装饰器示例,使用了 Python 的装饰器语法。

首先,定义了一个装饰器函数 log,该函数接受一个函数 func 作为参数。装饰器的作用是在函数执行前后打印日志。

  1. def log(func)定义了装饰器函数 log,接受一个函数作为参数,这个函数将被装饰。

  2. def wrapper(*arg, **kw): 在装饰器内部定义了一个内部函数 wrapper,它接受任意数量的位置参数 arg 和关键字参数 kw。这里使用 *arg **kw 来接收任意数量的参数。

  3. print('Start%s' % func): 在函数执行前打印日志信息,使用了 % 格式化字符串来将 func 的字符串表示插入日志中。

  4. return func(*arg, **kw): 调用被装饰的原始函数 func,并将接收到的参数传递给它。返回原始函数的结果。

  5. 这里使用 @log 语法将装饰器应用到了三个函数 func_afunc_b func_c 上。这相当于执行了以下操作:

func_a = log(func_a)
func_b = log(func_b)
func_c = log(func_c)

这样,每当调用这些函数时,实际上是调用了被装饰后的版本,这些版本在执行前后会打印日志信息。

理解Flask框架:一个小的Flask应用

from flask import Flask
app = Flask(__name__)@app.route('/')
def hello_world():return 'Hello World!'if __name__ == '__main__':app.run()

运行上面代码,在浏览器上输入http://127.0.0.1:5000/,便会看到 Hello World! 字样。

那么,这段代码做了什么?

1.首先导入了Flask类。这个类的实例是WSGI应用程序

2.接下来,我们创建一个该类的实例,第一个参数是应用模块或者包的名称,如果使用单一的模块,应该使用name,因为模块的名称将会因其作为单独应用启动还是作为模块导入而有不同

3.然后,我们使用route()装饰器告诉Flask什么样的URL能够触发我们的函数。

4.这个函数的名字也在生成 URL 时被特定的函数采用,这个函数返回我们想要显示在用户浏览器中的信息。

5.最后使用run()函数来让应用运行在本地服务器上。其中if__name__=='main':确保服务器只会在该脚本被Python解释器直接执行的时候才会运行,而不是作为模块导入的时候。

如果启用了调试支持,服务器会在代码修改后自动重新载入,并在发生错误时提供一个相当有用的调试器。启动调试,app.run(debug=True);并且route()装饰器把一个函数绑定到对应的URL上。如下例子

@app.route('/')
def index():return 'Index Page'@app.route('/hello')
def hello():return 'Hello World'

其中还是可以构造含有动态部分的URL,要给 URL 添加变量部分,可以把这些特殊的字段标记为 <variable_name> , 这个部分将会作为命名参数传递到函数。规则可以用 <converter:variable_name> 指定一个可选的转换器,如下例子。

@app.route('/user/<username>')
def show_user_profile(username):# show the user profile for that userreturn 'User %s' % username@app.route('/post/<int:post_id>')
def show_post(post_id):# show the post with the given id, the id is an integerreturn 'Post %d' % post_id

如果Flask能匹配URL,也是可以生成URL的。用url_for()来给指定的函数构造URL。它接受函数名作为第一个参数,也接受对应 URL 规则的变量部分的命名参数。未知变量部分会添加到 URL 末尾作为查询参数。这里有一些例子:

from flask import Flask, url_for
>>> app = Flask(__name__)
>>> @app.route('/')
... def index(): pass
...
>>> @app.route('/login')
... def login(): pass
...
>>> @app.route('/user/<username>')
... def profile(username): pass
...
>>> with app.test_request_context():
...  print url_for('index')  #/
...  print url_for('login')   #/login
...  print url_for('login', next='/')  #/login?next=/
...  print url_for('profile', username='John Doe')
...    #/user/John%20Doe

HTTP(与web应用会话的协议)有许多不同的访问URL方法。默认情况下,路由只回应GET请求,但是通过route()装饰器传递methods参数可以改变这个行为。

@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':do_the_login()else:show_the_login_form()

使用Python Flask 实现Restful API 

        Flask 是一个轻量级Web框架,可以实现快速的 Web 开发,并且提供了良好的扩展性。另外,Flask 还为实现 Restful API 提供了很多方便的工具,如Flask Restful 和 Flask Restplus 等。Flask 的代码结构简单,上手容易,比 Django 等其他框架更为轻量级,更适合快速迭代。

安装 Flask

首先,我们需要安装 Flask。可以使用 pip 命令来安装:

pip install flask
  创建 Flask 应用

首先,我们需要导入 Flask 模块,并创建一个 Flask 应用实例:

from flask import Flaskapp = Flask(__name__)

这里的 __name__ 参数表示当前模块的名字,Flask 根据这个参数来确定应用的根目录。

定义 API 路由

接下来,我们需要定义 API 的路由和处理函数。在 Flask 中,可以使用 @app.route 装饰器来定义路由:

@app.route('/users', methods=['GET'])
def get_users():return jsonify(users)

这里的 /users 表示路由的路径,methods=['GET'] 表示这个路由只支持 GET 方法。get_users 函数是这个路由的处理函数,它返回一个 JSON 格式的用户列表。

同样的,我们还可以定义其他路由和处理函数,比如获取指定用户信息、添加用户、修改用户信息和删除用户等。

处理请求参数

在 RESTful API 中,客户端通常需要向服务器传递一些参数,比如查询条件、请求体等。在 Flask 中,可以使用 request 对象来访问这些参数:

user = {'id': request.json['id'], 'name': request.json['name'], 'age': request.json['age']}

这里的 request.json 表示请求体中的 JSON 数据。如果请求体不是 JSON 格式,可以使用 request.form 或 request.args 来获取表单数据或查询参数。

返回 JSON 数据

在 RESTful API 中,通常需要返回 JSON 格式的数据。在 Flask 中,可以使用 jsonify 函数来将 Python 对象转换为 JSON 格式的数据:

return jsonify(users)

这里的 users 是一个 Python 列表对象,jsonify(users) 将它转换为 JSON 格式的数据,并返回给客户端。

启动应用

最后,我们需要在应用中启动 Flask 服务器:

if __name__ == '__main__':app.run()

这里的 __name__ 参数表示当前模块的名字,app.run() 表示启动 Flask 服务器,默认监听在本地的 5000 端口上。如果需要修改监听地址或端口,可以使用 host 和 port 参数来指定。

编写代码

下面是一个简单的 Flask 应用,它实现了一个简单的 RESTful API,用于获取和修改用户信息:

from flask import Flask, jsonify, requestapp = Flask(__name__)# 用户数据(模拟数据库)
users = [{"id": 1, "name": "Alice", "age": 20},{"id": 2, "name": "Bob", "age": 25},{"id": 3, "name": "Charlie", "age": 30},
]# 获取所有用户信息
@app.route('/users', methods=['GET'])
def get_users():return jsonify(users)# 获取指定用户信息
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):user = next((user for user in users if user['id'] == user_id), None)if user:return jsonify(user)else:return jsonify({'error': 'User not found'})# 添加用户
@app.route('/users', methods=['POST'])
def add_user():user = {'id': request.json['id'], 'name': request.json['name'], 'age': request.json['age']}users.append(user)return jsonify(user)# 修改用户信息
@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):user = next((user for user in users if user['id'] == user_id), None)if user:user['name'] = request.json.get('name', user['name'])user['age'] = request.json.get('age', user['age'])return jsonify(user)else:return jsonify({'error': 'User not found'})# 删除用户
@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):user = next((user for user in users if user['id'] == user_id), None)if user:users.remove(user)return jsonify({'result': True})else:return jsonify({'error': 'User not found'})if __name__ == '__main__':app.run()
测试 API

启动应用后,我们可以使用 curl 命令或其他工具来测试 API:

# 获取所有用户信息
curl http://localhost:5000/users# 获取指定用户信息
curl http://localhost:5000/users/1# 添加用户
curl -H "Content-Type: application/json" -X POST -d "{\"id\": 4, \"name\": \"David\", \"age\": 35}" http://localhost:5000/users# 修改用户信息
curl -H "Content-Type: application/json" -X PUT -d "{\"name\": \"Alice Smith\", \"age\": 22}" http://localhost:5000/users/1# 删除用户
curl -X DELETE http://localhost:5000/users/4

在 Windows 的命令提示符中,需要使用双引号 " 对 JSON 数据进行引用,并且在内部的双引号前面加上反斜杠 \ 进行转义。

参考:​​​​​​​

用Python 的Flask实现 RESTful API(学习篇)

通过Flask框架创建灵活的、可扩展的Web Restful API服务 - 知乎 (zhihu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/478090.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# CAD2016 多边形顶点按方向重新排序

多边形顶点按方向重新排序 初始化多边形顶点集合 outerPoints 创建一个名为 outerPoints 的 List<Point2d>&#xff0c;用于存储多边形的所有顶点坐标。 计算多边形顶点集合的边界框&#xff08;BoundingBox&#xff09; 使用LINQ的Aggregate方法遍历整个outerPoints列表…

金融云行业研究:预计2029年将达到626亿美元

金融云是指金融机构利用云计算模型构成原理&#xff0c;将自身数据、客户、流程及价值通过数据中心、客户端等技术手段分散到“云”中&#xff0c;以提高金融机构迅速发现并解决问题的能力&#xff0c;提升整体工作效率&#xff0c;改善流程&#xff0c;降低运营成本&#xff0…

代码随想录算法训练营29期|day54 任务以及具体安排

第九章 动态规划part11 123.买卖股票的最佳时机III // 版本一 class Solution {public int maxProfit(int[] prices) {int len prices.length;// 边界判断, 题目中 length > 1, 所以可省去if (prices.length 0) return 0;/** 定义 5 种状态:* 0: 没有操作, 1: 第一次买入…

VUE3 中导入Visio 图形

微软的Visio是一个功能强大的图形设计工具&#xff0c;它能够绘制流程图&#xff0c;P&ID&#xff0c;UML 类图等工程设计中常用的图形。它要比其它图形设计软件要简单许多。以后我的博文中将更多地使用VISO 来绘制图形。之前我一直使用的是corelDraw。 Visio 已经在工程设…

grid新建主从一对多

目录 总结一、步骤前端1.第一步-编写tabs的modelBody2.第二步编辑表扩展js 后端--重写表的add和Update方法1.第一步 总结 编写tabs的modelBody后编辑表扩展js在重写后端partial的Service 一、步骤 前端 1.第一步-编写tabs的modelBody 复制下面代码该改的改 <template&…

白话微机:5.解释串行接口以及一些考研面试问题

一. 前言&#xff08;回顾世界观&#xff09; 很久很久以前&#xff0c;有这样一个世界&#xff0c;这个世界有着现实世界一样的元素&#xff1a;那里的人又有一个别的名字叫做“数据”&#xff0c;人有0有1&#xff1b;人们也有住房&#xff0c;这些住房在这个世界叫做“存储器…

IO进程线程作业day2

使用fread和fwrite完成两个图片文件的拷贝 #include <myhead.h> #define high 541 #define wide 541 int main(int argc, const char *argv[]) {//以只读的方式打开图片文件1.bmpFILE *fp NULL;if((fp fopen("./1.bmp", "r")) NULL){perror(&qu…

【C语言】位操作符与移位操作符练习

目录 前言&#xff1a; 1.一道变态的面试题 2.输入一个整数 n &#xff0c;输出该数32位二进制表示中1的个数。其中负数用补码表示。 方法一&#xff1a; 方法二&#xff1a; 方法三&#xff1a; 3.打印整数二进制的奇数位和偶数位 前言&#xff1a; 前篇我们学习过C语言…

【漏洞复现-通达OA】通达OA WHERE_STR 存在前台SQL注入漏洞

一、漏洞简介 通达OA(Office Anywhere网络智能办公系统)是由北京通达信科科技有限公司自主研发的协同办公自动化软件,是与中国企业管理实践相结合形成的综合管理办公平台。通达OA WHERE_STR存在前台SQL注入漏洞,攻击者可通过该漏洞获取数据库敏感信息。 二、影响版本 ●…

《白话C++》第10章 STL和boost,Page85 std::shared_ptr常用功能

std::shared_ptr基本用法包括&#xff1a; &#xff08;1&#xff09;取裸指针 //get()成员取回裸指针 std::shared_ptr <int> pa(new int(5)); int* p pa.get(); /**< 取回裸指针 */ &#xff08;2&#xff09;判断是否为空 肯定可以这样写&#xff1a; std::s…

STM32-点亮 LED

目录 1 、电路构成及原理图 2 、编写实现代码 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 本人使用的是朗峰 STM32F103 系列开发板&#xff0c;此笔记基于这款开发板记录。 1 、电路构成及原理图 首先&#xff0c;通过朗峰 F1 开发板 LED 部分原理图看到…

接口频繁请求,被刷爆怎么办

目录 前言 1 防火墙 2 验证码 3 鉴权 4 IP白名单 5 数据加密 6 限流 7 监控 8 网关 前言 在面试时&#xff0c;经常会被问一个问题&#xff1a;如何防止别人恶意刷接口&#xff1f; 这是一个非常有意思的问题&#xff0c;防范措施挺多的。今天这篇文章专门跟大家一起…