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+y
    return 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 = 0
    for n in numbers:
        sum = sum + n * n
    return 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'%func
        return 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 user
    return '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 integer
    return '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 Flask

app = 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, request

app = 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)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PostgreSQL面试题-灿总题

面试题来源 &#xff1a;PostgreSQL学徒 PostgreSQL面试题集锦 已有的答案&#xff1a;Hehuyi_In 《PostgreSQL面试题集锦》学习与回答 一、MVCC 实现机制以及和 Oracle 的差异 ORACLE&#xff0c;MYSQL都是使用的UNDO来实现多版本并发控制&#xff0c;undo条目记录在从额外…

多维时序 | Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、BiLSTM的多变量时间序列预测

多维时序 | Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、BiLSTM的多变量时间序列预测 目录 多维时序 | Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、BiLSTM的多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现基于VMD-DBO-BiLSTM、VMD-BiLSTM、…

说一下JVM类加载机制?

Java中的所有类&#xff0c;都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类&#xff0c;而它的工作就是把class文件从硬盘读取到内存中。 在写程序的时候&#xff0c;我们几乎不需要关心类的加载&#xff0c;因为这些都是隐式装载的&#xff0c;除非我们有特殊…

HTB pwn Bad gradesRestaurant

Bad grades 没有开启ASLR 在功能2存在越界写,虽然有canary但是可以通过输入’-绕过。 输入数据可以利用python的struct解包成双精度浮点数,做了这些就是常规的ROP环节了。 exp from pwn import * def gd():gdb.attach(p)pause() def htd(hex_value):binary hex_value.to_b…

使用 Nginx 将部署多个子域名http服务重定向到https服务

首先在阿里云解析对应的子域名 打开自己的域名解析 点击添加记录 然后在nginx的配置文件下新增以下内容 # ssl证书地址,是你自己服务器上证书存放的地址 ssl_certificate /ssl/fullchain.cer; ssl_certificate_key /ssl/cert.key;#请按照以下协议配置 ssl_protocols…

JS基础(语法结构变量数据类型运算符流程控制)

JS基础(语法结构/变量/数据类型/运算符/流程控制) 目录 JS基础(语法结构/变量/数据类型/运算符/流程控制)什么是js&#xff1f;注释语法语法结构引入方式【1】script标签内部直接书写js代码【2】script标签src属性引入外部js代码 JS基础数据类型变量与常量变量的定义常量的定义…

OpenHarmony JS和TS三方组件使用指导

OpenHarmony JS和TS三方组件介绍 OpenHarmony JS和TS三方组件使用的是OpenHarmony静态共享包&#xff0c;即HAR(Harmony Archive)&#xff0c;可以包含js/ts代码、c库、资源和配置文件。通过HAR&#xff0c;可以实现多个模块或者多个工程共享ArkUI组件、资源等相关代码。HAR不…

calcite在flink中的二次开发,介绍解析器与优化器

calcite 在flink中的二次开发 1 CodeGen2 flink 语法扩展2.1 在进行 Rule 规则匹配时&#xff0c;放开对 Distinct 的限制2.2下面附上一个 利用codegen来生成所需类的例子&#xff1a; 3 flink使用calcite 生成解析器FlinkSqlParserImpl3.1 FlinkSqlParserImpl 的生成3.1.1 fli…

[SwiftUI]启动页LaunchScreen.storyboard中适配状态栏加安全区域的高度

如下图&#xff0c;我有一个需求。在启动页&#xff08;LaunchScreen.storyboard&#xff09;和引导页&#xff08;GuideView&#xff09;的黑色背景上&#xff0c;使用了同一张正方形图片。要求从启动页切换到引导页时&#xff0c;这两张相同的图片的过渡要无缝衔接&#xff0…

redis的缓存穿透,缓存并发,缓存雪崩,缓存问题及解决方案

缓存穿透 问题原因 解决方案 缓存并发 缓存雪崩 缓存失效时间设置一致导致的。 解决方案&#xff1a; 1&#xff09;方案一 2&#xff09;方案二 如何设计一个缓存策略&#xff0c;缓存热点数据&#xff1f;

【2024年湖北二建报考条件解析】不限专业,满足条件就能参加考试

【2024年湖北二建报考条件解析】不限专业&#xff0c;满足条件就能参加考试 2024年湖北二建报考疑问汇总&#xff0c;就近报考轻松搞定&#xff01; 2024年湖北省二级建造师/二建报考重点梳理 2024年湖北二建网上报名时间2月28号-3月12日。想要考二建的老铁千万不要错过一年一…

Centos安装图形化桌面环境

1.使用root远程登录最小化安装的虚拟机 2.执行命令yum groupinstall "X Window System" 这是安装窗口系统 3.执行命令yum grouplist" 检查安装的软件可可以安装的软件 4.执行命令yum groupinstall "Server with GUI" 这是安装图形化界面 5.执行命令sy…

Vision Transfomer系列第二节---Tricks测试

目录 学习式和固定式位置编码测试dropout的作用测试block深度的作用测试embeding维度大小的作用测试多头的作用测试Overlap Patch的作用 学习式和固定式位置编码测试 主要测试无位置编码\可学习位置编码和固定式位置编码的训练效果: 其中固定式位置编码采用之前博客的正余弦位…

组件嵌套-传递参数

组件嵌套 这里的嵌套&#xff0c;就相当于不同的界面组合进在外层的root界面。每个部分都是独立的。 数据传递&#xff08;父→子&#xff09; 理论上通过props可以传递任何类型的数据&#xff0c;需要注意的是&#xff0c;子组件可以接收父组件的值&#xff0c;不能父组件接收…

缓存驱动联邦学习架构赋能个性化边缘智能 | TMC 2024

缓存驱动联邦学习架构赋能个性化边缘智能 | TMC 2024 伴随着移动设备的普及与终端数据的爆炸式增长&#xff0c;边缘智能&#xff08;Edge Intelligence, EI&#xff09;逐渐成为研究领域的前沿。在这一浪潮中&#xff0c;联邦学习&#xff08;Federated Learning, FL&#xf…

Java学习小记——设计模式

设计模式 设计模式简介Singleton模式Singleton模式简介Singleton的创建双重锁模式Double checked locking作为Java类的静态变量 变继承关系为组合关系组合模式装饰器模式 如何创建对象抽象工厂模式 设计模式简介 设计模式&#xff08;Design pattern&#xff09;代表了最佳的实…

C# OpenCvSharp DNN Low Light image Enhancement

目录 介绍 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN Low Light image Enhancement 介绍 github地址&#xff1a;https://github.com/zhenqifu/PairLIE 效果 模型信息 Model Properties ------------------------- ------------------------------------------…

Maven的初步认识

Maven 1,Maven 简介 Maven是Apache软件基金会的一个开源项目,是一个优秀的项目构建工具,他用来帮助开发者管理项目中的jar包以及jar之间的依赖关系,完成项目的编译,测试,打包发布等工作. Maven中的概念 pom(Project Object Model 项目对象模型) maven 管理项目的根目录下 都…

WebRTC最新版报错解决:FileNotFoundError: LASTCHANGE.committime (二十五)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

【k8s初始化过程解析】

k8s初始化过程解析 [rootk8s-master ~]# kubeadm init –apiserver-advertise-address10.10.10.100 –image-repository registry.aliyuncs.com/google_containers –kubernetes-version v1.25.0 –service-cidr10.1.0.0/16 –pod-network-cidr10.2.0.0/16 –cri-socket …