Python中的API构建指南:在Flask中进行API开发

news2024/11/16 12:04:05

原文:Python中的API构建指南:在Flask中进行API开发 - 知乎

如何实现从一个软件与另一个软件的通信交互?就像我们的APP,如何实现微信支付、苹果支付?

其实,我们只需要一个API。

API(应用程序编程接口)是一个简单的接口,它定义了可以发出的请求类型(需求/问题等)、请求的发出方式以及处理方式。

在本文中,我们将构建一个API,它允许我们向不同的端点发送一系列GET/POST/PUT/PATCH/DELETE等各种请求,并返回或修改与API连接的数据。

我们将使用Flask框架来创建我们的API,并使用Postman来对其进行测试它。本文将涵盖以下内容:

1.设置

  • 数据集
  • 初始化Flask API
  • 端点
  • 运行本地服务器

2.编写API

  • GET
  • POST
  • 401未经授权
  • PUT
  • DELETE
  • 用户类(摘要)

3.总结


设置

我们的API将包含两个端点:用户和位置。 前者将允许访问我们注册用户的详细信息,而后者将包括咖啡馆位置列表。

此处假设的用例是数百万个咖啡馆的书签应用程序,用户可以在其中打开该应用程序并为自己喜欢的咖啡馆添加书签,例如谷歌地图。

1.数据集

为了简单起见,我们将把这些数据存储在两个本地CSV文件中。

CSV文件如下所示:

用户数据

位置数据

users.csv:https://drive.google.com/file/d/12-nW-R6TEPbUzSVF8zsQtOm992TdZOqj/view?usp=sharing

locations.csv:https://drive.google.com/file/d/1ERGeiKZLNuD9K-MHd7a0Colqj_DqiMww/view?usp=sharing

2.初始化Flask API

对于Python脚本,我们需要导入模块并初始化API,如下所示:

from flask import Flask
from flask_restful import Resource, Api, reqparse
import pandas as pd
import ast
app = Flask(__name__)
api = Api(app)

3.端点

正如上文提到的,我们的API有两个端点:用户和位置。

假设我们的API的结果位于http://www.api.com网站,则将在http://www.api.com/users提供与Users类的通信,并在http://www.api.com/locations提供Locations。

为了创建端点,我们需要定义一个Python类,然后使用api.add_resource将其连接到所需的端点,如下所示:

class Users(Resource):
    # 方法在这里
    pass

api.add_resource(Users, '/users')  # /users'是我们的切入点
  • Flask需要知道类是我们API的端点,因此我们将Resource与类定义一起传入。
  • 在类内部,包含了我们的HTTP方法(GET,POST,DELETE等)。
  • 最后,我们使用api.add_resource将Users类与/ users端点链接。

因为我们需要两个端点,所以我们复制了逻辑:

class Users(Resource):
    #方法
    pass
    
class Locations(Resource):
    #方法
    pass
    
api.add_resource(Users, '/users')  # '/users' 是我们进入用户的切入点
api.add_resource(Locations, '/locations')  #  '/ locations'是我们的位置的切入点

4.运行本地服务器

最后,在我们写出API时,还要对其进行测试!

为此,我们需要托管我们的API,我们可以在本地通过将app.run添加到脚本末尾来进行本地化,如下所示:

if __name__ == '__main__':
    app.run()  #运行 Flask app

当我们运行脚本时,我们会看到如下所示:

初始化本地主机服务器

设置好服务器后,如果您在使用Postman构建API的实际标准之前还没有使用过它,就可以对其进行测试。

编写API

在每个类中,我们保留HTTP方法GET,POST和DELETE。

要创建GET方法,我们使用def get(self)。POST和DELETE遵循相同的模式。

1.GET

GET方法是最简单的。我们返回存储在字典中的 users.csv 中存储的所有数据,如下所示:

class Users(Resources):
    def get(self):
        data = pd.read_csv('users.csv')  # 读取 CSV
        data = data.to_dict()  # 将数据帧转换为字典
        return {'data': data}, 200  # 返回数据和200 OK代码

然后,我们可以运行脚本来初始化我们的API,打开Postman并将GET请求发送到我们的本地主机地址(通常为http://127.0.0.1:5000),这是我们的API入口点。

如何将GET请求发送到我们的API

要将GET请求发送到Postman中的API,我们:

  1. 从下拉列表中选择GET;
  2. 输入我们的API实例+ / users的入口点(端点);
  3. 点击发送;
  4. 检查我们的API返回的状态码(我们应该看到200 OK);
  5. 查看我们的API响应,即JSON(如字典)格式的users.csv。

2.POST

POST方法允许我们将记录添加到数据中。在这种情况下,我们将使用 usedId,name和city的参数。

这些参数作为URL参数传递到我们的API端点,如下所示:

http://127.0.0.1:5000/users?userId=abc123&name=The Rock&city=Los Angeles

我们可以指定所需的参数,然后使用reqparse解析提供的值,如下所示:

parser = reqparse.RequestParser()  # 初始化

parser.add_argument('userId', required=True)  # 添加参数
parser.add_argument('name', required=True)
parser.add_argument('city', required=True)

args = parser.parse_args()  # 将参数解析为字典

让我们分解一下解析器代码:

  • 使用.RequestParser()初始化解析器。
  • 使用.add_argument([arg_name],required)添加参数。请注意,required = True 表示请求中的参数是必需的。另外,我们可以添加带有 required = False 的可选参数。
  • 使用.parse_args()将参数及其值解析为Python字典。

然后,我们可以访问传递给每个参数的值,就像我们通常在字典中使用键值对一样。

将代码进行合并,为CSV添加值:

class Users(Resource):
    def post(self):
        parser = reqparse.RequestParser()  #初始化
        
        parser.add_argument('userId', required=True)  # 添加参数
        parser.add_argument('name', required=True)
        parser.add_argument('city', required=True)
        
        args = parser.parse_args()  #将参数解析为字典
        
        # 创建包含新值的新数据帧
        new_data = pd.DataFrame({
            'userId': args['userId'],
            'name': args['name'],
            'city': args['city'],
            'locations': [[]]
        })
        # 读取CSV
        data = pd.read_csv('users.csv')
        # 添加新提供的值
        data = data.append(new_data, ignore_index=True)
        # 保存并返回CSV
        data.to_csv('users.csv', index=False)
        return {'data': data.to_dict()}, 200  # 返回200 OK数据

看起来有点混乱,简单点,我们要做的就是:

  • 从URL参数args创建一行新数据new_data;
  • 将其附加到预先存在的数据;
  • 保存新合并的数据;
  • 返回数据以及200 OK状态代码。

我们通过向/ user端点发送包含userId,名称和城市参数的POST请求来创建新用户。

现在,我们可以发送POST请求来创建新用户了,是不是很简单?!

3.401未经授权

我们的代码处理POST请求,允许我们将新数据写入users.csv ,但是如果该用户已经存在怎么办?

为此,我们需要添加一个检查操作。如果 userId 已经存在,我们将向用户返回401未经授权的代码。

...

        # 读取 CSV
        data = pd.read_csv('users.csv')

        if args['userId'] in data['userId']:
            return {
                'message': f"'{args['userId']}' already exists."
            }, 401
        else:
            # 创建包含新值的新数据帧
            new_data = pd.DataFrame({
                'userId': args['userId'],
                'name': args['name'],
                'city': args['city'],
                'locations': [[]]
            })
            # 添加新提供的值
            data = data.append(new_data, ignore_index=True)
            data.to_csv('users.csv', index=False)  # 返回并保存CSV
            return {'data': data.to_dict()}, 200  # 返回200 OK的数据

如果我们尝试使用用户ID“ abc123”再次发布,我们将返回以下401未经授权的状态代码和消息

回到Postman,我们可以通过尝试两次添加同一用户来测试我们的API是否正常运行。这次,The Rock收到401未经授权的响应。

4.PUT

如果我们想为用户添加咖啡馆怎么办? 我们无法使用POST,因为它会返回401未经授权的代码,这时候,我们就要用PUT了。

与POST类似,在提供的 userId 不存在的情况下,我们需要添加 if-else 逻辑。

class Users(Resource):
    def put(self):
        parser = reqparse.RequestParser()  # 初始化
        parser.add_argument('userId', required=True)  # 添加参数
        parser.add_argument('location', required=True)
        args = parser.parse_args()  # 将参数解析为字典

        # 读取 CSV
        data = pd.read_csv('users.csv')
        
        if args['userId'] in list(data['userId']):
            #将列表字符串评估为列表
            data['locations'] = data['locations'].apply(
                lambda x: ast.literal_eval(x)
            )
            # 选取用户
            user_data = data[data['userId'] == args['userId']]

            # 更新用户的位置
            user_data['locations'] = user_data['locations'].values[0] \
                .append(args['location'])
            
            # 保存并返回CSV
            data.to_csv('users.csv', index=False)
            # 返回数据和200 OK
            return {'data': data.to_dict()}, 200

        else:
            # 否则userId不存在
            return {
                'message': f"'{args['userId']}' user not found."
            }, 404

除了对代码进行一些小调整之外,我们的PUT方法几乎与POST相同。

在这里,我们使用PUT方法将ID为0007的咖啡馆添加到The Rock的加标签的位置

回到Postman,我们所需的输入参数已更改。 现在,我们只需要userId和一个位置即可添加到用户添加了书签的位置。

5.DELETE

我们还可以使用DELETE方法删除记录。

此方法非常简单,我们需要指定要删除的userId,并在不存在userId的情况下添加一些if-else逻辑。

例如,如果用户 Jill 认为我们的APP没有用并且想离开,我们将发送包含她的userId的DELETE请求。

发送对userId'b2c'的DELETE请求会从我们的用户数据中删除Jill的记录

我们可以在Postman中进行测试,并且可以预期的是,我们返回的数据没有Jill的记录。如果我们想删除不存在的用户怎么办?

6.Users Class

这就是构成Users类的所有部分,可以通过我们的 /users 端点进行访问。

之后,我们仍然需要将 Locations 类放在一起。这个其他类应允许我们获取、发布、修补(更新)和删除位置。

每个位置都有一个唯一的ID,当用户为一个位置添加书签时,该唯一ID将通过PUT / users添加到其位置列表中。

这段代码与我们在Users类中编写的代码没有太大区别,在此,我们不再重复。

总结

使用Flask和Python设置API的方法非常简单。

通过学习上文,我们就有了一种易于使用的标准化方法,可以在不同接口之间进行通信交互。

在本文中,介绍了所有最常见的请求方法:GET、POST、PUT和DELETE。以及一些HTTP状态代码:200、401和404

最后,我们还学习了如何在本地托管我们的API并通过 Postman 对其进行测试,从而让我们能够快速诊断问题并确保我们的API正常运行。

总而言之,API开发对于开发人员来说,几乎是任何其他技术领域都是至关重要的技能。

--END--

上文中的所有代码,都能在GitHub上找到:https://gist.github.com/jamescalam/0b309d275999f9df26fa063602753f73

如果你对人工智能感兴趣,那么一定要关注我们!

如果喜欢本文,欢迎转发、评论、收藏~

也可以关注我们的公众号:为AI呐喊(weainahan)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【二叉树入门指南】链式结构的实现

【二叉树入门指南】链式结构的实现 一、前置说明二、二叉树的遍历2.1前序遍历2.2中序遍历2.3 后序遍历 三、以前序遍历为例,递归图解四、层序遍历五、节点个数以及高度等5.1 二叉树节点个数5.2二叉树叶子节点个数5.3 二叉树第k层节点个数5.4 二叉树查找值为x的节点5…

黑客资料(基本概念,漏登平台,kali安装)

黑客资料 1.基本概念 1.1安全三要素 1.2 渗透测试 在拥有授权的前提下,模拟黑客的攻击手段进行测试,也被称为道德黑客 1.3 渗透测试的意义 1.4 渗透测试的流程 1.5 确定目标 这个确定目标,主要对范围进行测试,对那些设备&#…

【线程池】线程池拒绝策略还有这个大坑(二)

目录 踩坑代码 后果展示 原因 小结 概要 上文我们聊了聊阻塞队列,有需要的小伙伴可以去瞅瞅【线程池】换个姿势来看线程池中不一样的阻塞队列(一)_走了一些弯路的博客-CSDN博客 这波我们一起来研究下线程池的拒绝策略。 你肯定要说了&a…

odejs+vue+elementui个人图片电子相册网站_84ds3

系统阐述的是使用智能化电子相册系统的设计与实现,对于nodejs、B/S结构、MySQL进行了较为深入的学习与应用。主要针对系统的设计,描述,实现和分析与测试方面来表明开发的过程。开发中使用了vue.js框架和MySQL数据库技术搭建系统的整体架构。利…

gitcode中删除已有的项目

镜像地址: https://www.jianshu.com/p/504c1418adb7?v1693021320653 扩展阅读 如何在GitLab中删除一个项目 https://www.codenong.com/cs106866762/ 简介: 如何在GitLab中删除一个项目 最近GIT上建了太多项目。想清一下,就在网上查了查…

27台光刻机,ASML做出了选择,无法割舍中国市场

日前ASML公布的业绩显示二季度它对中国市场的光刻机出货量环比猛增两倍多至27台,显示出ASML对中国市场的重视,为何在荷兰决定自9月1日起限制对中国供应先进芯片设备之时,ASML却突然加大了对中国的光刻机供货力度呢? ASML虽然垄断着…

Ruoyi微服务启动流程

1、执行sql 执行sql ry-quarty.sql ry_2023706.sql 到ry-cloud 数据库 2、下载nacos 修改配置文件 修改连接地址 启动nacos 看到下面的配置文件即为成功 修改配置文件里面的数据库连接信息 3、修改nacos 为单机启动 4、启动项目即可 nacos自取 链接: https://pan.baidu…

如何提高企业的维修效率?智能维修设备管理系统有什么作用?

随着工业4.0的不断发展,智能维修设备管理系统已经成为了企业提高维修效率、降低维修成本、优化资源利用的重要工具。本文将介绍智能维修设备管理系统的优势以及推荐使用“的修”平台设备管理系统的理由。 一、智能维修设备管理系统的优势   智能维修设备管理系统通…

PHP8函数的引用和取消-PHP8知识详解

今天分享的是php8函数的引用和取消,不过在PHP官方的参考手册中,已经删除了此类教程。 1、函数的引用 在PHP8中不管是自定义函数还是内置函数,都可以直接简单的通过函数名调佣。函数的引用大致有下面3种: 1.1、如果是PHP的内置函…

暑期习题练习 C语言

编程能力小提升! 前言一、转义字符二、重命名与宏定义三、三目运算符四、计算日期到天数转换五、计算字符串长度六、宏定义应用七、const常量八、C语言基础九、const常量(二)十、符号运算十一、记负均正十二、SWITCH,CASE十三、错…

阿桂天山的技术小结:Flask+UEditor实现图片文件上传富文本编辑

话不多说,有图有源码 先看效果: 1.前端html页面index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><script src"{{ url_for(static,filenameueditor/ueditor.config.js) }}"></script…

pytest执行顺序,不要迷恋pytest-order

所以说pytest的执行顺序是默认编写的顺序来执行的 笔者在编写场景化测试用例时 test_违规告警_未报备空进重出.py 使用了order 序号1-12来进行排序 test_违规告警_未报备重进空出.py 使用了order 序号1-12来进行排序&#xff0c;执行时导致先会执行两个文件夹中order1的用例造成…

C语言练习3(巩固提升)

C语言练习3 选择题 选择题 前言 奋斗是曲折的&#xff0c;“为有牺牲多壮志&#xff0c;敢教日月换新天”&#xff0c;要奋斗就会有牺牲&#xff0c;我们要始终发扬大无畏精神和无私奉献精神。奋斗者是精神最为富足的人&#xff0c;也是最懂得幸福、最享受幸福的人。正如马克思…

2023科隆游戏展开幕~黑神话等多款国产游戏亮相

这是【游戏开发那些事】第62篇原创 科隆游戏展&#xff0c;全名科隆国际游戏娱乐展览会&#xff08;Gamescom&#xff09;&#xff0c;是世界上最大的电子游戏展览之一。由德国联邦协会互动娱乐软件&#xff08;BIU&#xff09;主办&#xff0c;每年在德国科隆举行&#xff0c;…

探讨uniapp的路由与页面栈及参数传递问题

1首先引入页面栈 框架以栈的形式管理当前所有页面&#xff0c; 当发生路由切换的时候&#xff0c;页面栈的表现如下&#xff1a; 页面的路由操作无非&#xff1a;初始化、打开新页面、页面重定向、页面返回、tab切换、重加载。 2页面路由 uni-app 有两种页面路由跳转方式&am…

Activity之间的数据传递方法汇总

在Activity间传递的数据一般比较简单&#xff0c;但是有时候实际开发中也会传一些比较复杂的数据&#xff0c;本节一起来学习更多Activity间数据的传递方法。 1、通过 Intent 传递 我们在进行 Activity 跳转时&#xff0c;是要有 Intent&#xff0c;此时 Intent 是可以携带数…

Ai.Fy - Text To Image——AIGC工具

Ai.Fy 是一个功能强大的 Unity 编辑器扩展,可将文本转换为图像、粗略草图转换为纹理、AI 深度图、概念设计、生成自动法线贴图和平滑贴图。 以下是生成的案例 无需注册,无需API密钥,无需定期付款,无订阅费,无额外费用,无限制,只需单击即可在我们的模型上进行易于使用的…

action和mutation之间的利用 代码解释

场景&#xff1a;购物车点击按钮 context.commit(‘changeCount’, { goodsNum, goodsId })解释这段代码 这段代码是在使用 Vuex 进行状态管理时常见的一种写法。下面对代码进行解释&#xff1a; context.commit 是 Vuex 中的一个方法&#xff0c;用于触发一个名为 changeC…

iconfont 图标在vue里的使用

刚好项目需要使用一个iconfont的图标&#xff0c;所以记录一下这个过程 1、iconfont-阿里巴巴矢量图标库 这个注册一个账号&#xff0c;以便后续使用下载代码时需要 2、寻找自己需要的图标 我主要是找两个图标 &#xff0c;一个加号&#xff0c;一个减号&#xff0c;分别加入到…

Python“牵手”阿里巴巴商品列表数据,关键词搜索阿里巴巴API接口数据,阿里巴巴API接口申请指南

阿里巴巴平台API接口是为开发电商类应用程序而设计的一套完整的、跨浏览器、跨平台的接口规范&#xff0c;阿里巴巴API接口是指通过编程的方式&#xff0c;让开发者能够通过HTTP协议直接访问阿里巴巴平台的数据&#xff0c;包括商品信息、店铺信息、物流信息等&#xff0c;从而…