【玩转 Postman 接口测试与开发2_020】(完结篇)DIY 实战:随书示例 API 项目本地部署保姆级搭建教程(含完整调试过程)

book cover for the 2nd version

《API Testing and Development with Postman》最新第二版封面

文章目录

  • 最新版《Postman 接口测试与开发实战》示例 API 项目本地部署保姆级搭建教程
    • 1 前言
    • 2 准备工作
    • 3 具体部署
      • 3.1 将项目 Fork 到自己名下
      • 3.2 创建虚拟环境并安装依赖
      • 3.3 初始运行与项目调试
    • 4 示例项目的用法
    • 5 复盘与总结

写在前面
本篇完整介绍了贯穿全书的 todo-list 演示项目的本地部署过程,并结合亲身经历复盘了 AI 在整个过程中发挥的作用及今后应该注意的一些关键细节。一旦完成了该项目的本地部署,很多和项目本身无关的干扰因素都将降至最低,可以和本书作者的思路更加同步,还能进一步积累 Python 在 Web 应用快速开发方面的宝贵经验,可谓一举多得。本篇姑且可视为本次专栏的收尾篇,因为全书最主要的重点知识和难点环节都已经全部整理出来了。诚挚欢迎所有对 Postman 接口测试感兴趣的朋友前来交流心得,共同进步!

最新版《Postman 接口测试与开发实战》示例 API 项目本地部署保姆级搭建教程


1 前言

2025 年 2 月 7 日,我顺利完成了高分实战专栏《Postman接口测试与开发实战》最后一篇自学笔记的梳理。系统复盘时才发现 示例 API 项目 的本地化问题一直没有解决。该项目是一个用 Python 搭建的待办清单简易应用,不仅开放了 API 接口和 OpenAPI 文档页,还提供了一个简易页面方便进行 CRUD 操作:

图 1:示例 API 项目首页效果图

【图 1:示例 API 项目首页效果图】

我试过按照 README 的提示进行操作,结果服务端虽然启动成功了,一访问门户首页就报 500 异常;但是接口文档页(即 Swagger 接口页)又能正常打开。随后几天我又在 GitHub Copilot 的提示下了解了 DjangoFlask 以及 FastAPI 相关的知识,才慢慢对这个示例项目有了点感觉。趁着刚学完 FastAPI 集成 SQLite 的新鲜劲,今天再次挑战一举拿下,便有了这篇复盘文章。

一旦解决了该项目的本地部署问题,原书《API Testing and Development with Postman, Second Edition》中的配套练习就无需再用 GitPod 的线上环境来搭建了;苛刻的无操作超时的问题也消失了;后续遇到新的测试需求也能第一时间在本地直接调试验证,可谓一举多得。

最关键的是,借助这次调试 Python 项目的实战经历,我对 AI 辅助编程又有了更立体的认识。

2 准备工作

相关前置准备工作如下:

  • Gitv2.45.1(能克隆 GitHub 项目就行);
  • 一个有效的 GitHub 帐号;
  • Pythonv3.11 及以上(示例项目要求);
  • Anaconda Promptv24.11.3(方便创建 Python 虚拟环境);

3 具体部署

3.1 将项目 Fork 到自己名下

示例项目地址:https://github.com/djwester/todo-list-testing

为了方便后续二次开发,最好将原项目复刻到自己名下:

img16.1

图 2:复刻原项目到自己名下

【图 2:复刻原项目到自己名下】

$ (pwd).Path
D:\sandbox
$ git clone git@github.com:SafeWinter/todo-list-testing.git
$ cd todo-list-testing

实测效果图:

图 3:将 Fork 后的示例项目克隆到本地

【图 3:将 Fork 后的示例项目克隆到本地】

3.2 创建虚拟环境并安装依赖

本地项目代码就绪后,再来创建一个 Python 虚拟环境 todolist(在 Anaconda Prompt 命令行中实现):

# 查看当前环境列表
> conda env list# conda environments:
#
base                *  C:\Users\ad\anaconda3
myenv                  C:\Users\ad\anaconda3\envs\myenv# 新建 todolist 环境
> conda create --prefix D:\conda_venvs\todolist python=3.11
# 配置自定义虚拟环境所在路径
> conda config --add envs_dirs D:\conda_venvs
# 切到 todolist 环境
> conda activate todolist
# 确认当前环境
> conda env list# conda environments:
#
base                   C:\Users\ad\anaconda3
myenv                  C:\Users\ad\anaconda3\envs\myenv
todolist             * D:\conda_venvs\todolist
>

关于虚拟环境的删除

如果哪天不需要该环境,则可使用以下命令彻底删除:

# 使用 conda env remove 命令
> conda env remove --prefix=D:\conda_venvs\todolist
# 如果上述命令不成功,则可手动删除
> rm -rf D:\conda_venvs\todolist
# 清理 Conda 缓存和元数据
> conda clean --all
# 验证操作结果
> conda env list

注意:

  1. 删除虚拟环境后,所有安装在该环境中的包和数据都会被清除,且无法恢复
  2. 如果虚拟环境正在使用中(已激活状态),请先停用该环境:conda deactivate

虚拟环境搭好后,根据 README 文档,需要安装 poetry 依赖管理工具:

> curl -sSL https://install.python-poetry.org | python -

其中:

  • -s--silent):静默模式,不显示进度条或错误信息;
  • -S--show-error):与 -s 一起使用时,如果请求失败,curl 会显示错误信息;
  • -L--location):如果请求的 URL 有重定向,curl 会自动跟随重定向;
  • -:表示标准输入(stdin),用于将 curl 下载的内容直接传递给 python 解释器执行。

然后进入刚才的示例项目根路径,利用 poetry install 安装所需依赖项:

(D:\conda_venvs\todolist) C:\Users\ad> D:
(D:\conda_venvs\todolist) D:\> cd sandbox\todo-list-testing
(D:\conda_venvs\todolist) D:\sandbox\todo-list-testing> poetry install
Installing dependencies from lock filePackage operations: 54 installs, 0 updates, 0 removals- Installing mdurl (0.1.2)- Installing colorama (0.4.6)
# ...- Installing requests (2.32.3)- Installing sqlalchemy (2.0.31)Installing the current project: todo-list (0.1.0)
Error: The current project could not be installed: No file/folder found for package todo-list
If you do not want to install the current project use --no-root.
If you want to use Poetry only for dependency management but not for packaging, you can disable package mode by setting package-mode = false in your pyproject.toml file.
If you did intend to install the current project, you may need to set `packages` in your pyproject.toml file.(D:\conda_venvs\todolist) D:\sandbox\todo-list-testing> 

可以看到,安装到最后有个报错(其实并不影响项目启动):

图 4:执行 poetry install 到最后显示的报错界面(不影响)

【图 4:执行 poetry install 到最后显示的报错界面(不影响)】

也可以根据提示再次运行 poetry install --no-root,警告就消失了:

图 5:添加 --no-root 选项后依赖安装过程就不报错了

【图 5:添加 --no-root 选项后依赖安装过程就不报错了】

3.3 初始运行与项目调试

到了这一步,项目就初步具备启动条件了,执行命令 poetry run uvicorn main:app --reload 即可运行服务端:

图 6:直接通过 poetry run 启动后台服务端(运行正常)

【图 6:直接通过 poetry run 启动后台服务端(运行正常)】

但只要在浏览器中访问首页 URL http://127.0.0.1:8000 则会报错:

img16.8

图 7:在浏览器打开项目首页看到的页面及后台报错情况

【图 7:在浏览器打开项目首页看到的页面及后台报错情况】

但此时访问接口文档页(GET /docs)却能正常打开:

图 8:示例项目的接口文档页可以正常打开

【图 8:示例项目的接口文档页可以正常打开】

为什么会报错呢?其实控制台最后一句话已经提示得很明显了(我之前一直没仔细看):某语句在调用 startswith 属性时报了空指针异常;但是控制台并没有给出具体的文件位置。根据 README 的操作提示可以得知,这里跳过了复制生成 .envrc 文件的步骤,其中定义了一个只在 Linux 系统生效的环境变量 DATABASE_URL

# 漏掉的命令:cp .envrc.example .envrc
# .envrc.example 只有一个语句:
export DATABASE_URL="sqlite+pysqlite:///./sql_db.db"

这就说明报错来自数据库的初始化。其实也可以用 VSCode 全局检索关键字 startswith,即可锁定问题出处:

图 9:在 VSCode 中全局检索 startswith 锁定后端报错的具体出处

【图 9:在 VSCode 中全局检索 startswith 锁定后端报错的具体出处】

这样就定位到了三处包含 startswith 方法调用的文件,打开任意一个,例如 database.py,可以看到如下内容:

def db_session():uri = os.getenv("DATABASE_URL")if uri.startswith("postgres://"):uri = uri.replace("postgres://", "postgresql://", 1)engine = create_engine(uri)Session = sessionmaker(autocommit=False, autoflush=False, bind=engine)db = Session()maybe_initialize_db(db, engine)with Session() as session:yield sessionsession.close()

注意第 2 至 4 行,这表明 uri 是从环境变量中读取 DATABASE_URL 的值,且项目还支持 postgreSQL 数据库;可惜实际运行时读取失败了。

为了在 Windows 系统中实现快速启动,这里直接导入一个硬编码的 uri 模块,并令其取值为默认字符串 "sqlite+pysqlite:///./sql_db.db"

于是新建模块 database/uri.py 并输入以下内容:

uri = "sqlite+pysqlite:///./sql_db.db"

然后分别导入报错的那三个文件,并进行如下调整:

# database/database.py
from database.uri import uri
# ...
def db_session():engine = create_engine(uri)# ...# create_tables.py
from database.uri import uri
# ...
engine = create_engine(uri)# remove_tables.py
from database.uri import uri
# ...
engine = create_engine(uri)

改好后,再次刷新浏览器页面,就能看到项目首页了(启动服务端时加了 --reload 选项支持动态更新):

图 10:对 uri 模块进行硬编码导入后看到的项目首页效果

【图 10:对 uri 模块进行硬编码导入后看到的项目首页效果】

4 示例项目的用法

该项目看似简陋,其实还包含了很多必要的功能点:

  • 用户登录:用户名可以是 user1user2admin,登录密码均为 12345
  • 只有自己创建的待办事项可以被删除;
  • 页面上可以修改待办事项的几个状态:DraftIn ProgressComplete
  • 如果存在删不掉的数据,可退出运行,并执行数据库初始化命令:poetry run python remove_tables.py

如果想调用 API 接口,则可以打开 GET /docs 页面利用 OpenAPI 接口规范生成的标准接口进行测试(如获取登录令牌 POST /token):

图 11:在 OpenAPI 接口页尝试发送 POST 请求获取登录令牌

【图 11:在 OpenAPI 接口页尝试发送 POST 请求获取登录令牌】

更多操作步骤,可以结合源码进行二次开发,加深对 API 接口调试的理解。

5 复盘与总结

这次的项目本地化实战其实走了很多弯路:明明可以从后台报错信息中直接找到解决方案,之前的几次尝试我都忽略了这个关键细节,反而让 GH Copilot 列出项目用到的主要技术栈,然后一个一个地去了解、一个一个从零学起。这么做不能说没用,毕竟项目调试始终存在一定的偶然性,全面了解项目用到的技术栈可以大幅提高调试的一次通过率;只是对于这个项目而言有点杀鸡用牛刀了——最终的解决方案(导出 uri 模块)和任何一个 Python Web 框架本质上都没有任何关系。说到底还是自己的粗心大意白白耽误了一周多的时间。

另一方面也可以看到,强大如 CopilotDeepSeek 这样的 AI 工具,其实是无法快速帮我锁定这个漏掉的关键细节的。它们只会按我给的思路和提示词进行回答,从这个角度来看,当下这些炙手可热的 AI 工具似乎又过于笨拙——因为真正有经验的老程序员,是一定会先问我报了什么错再来确定具体的解决方案的。因此,用好 AI 的关键,其实就在于能否从自身出发,切实培养出一系列良好的软件开发习惯,比如:问题导向、低耦合高内聚、重视测试用例……不一而足;能否在大家都能使用 AI 模型指导编程实践的情况下,直达问题本质,率先找到突破口。

这次实战也再次印证了 AI 工具 遇强则强 的特点。或许,今后无论 AI 如何发展,人与人之间的各种差距,可能都不会因为 AI 智能的大幅提升而被彻底消除;更有可能出现的情况是进一步加深人们在认知层面上的 “贫富差距”。

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

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

相关文章

3-提前结束训练

一、核心类 class EarlyStopping:# YOLOv5 simple early stopperdef __init__(self, patience30):self.best_fitness 0.0 # i.e. mAPself.best_epoch 0self.patience patience or float(inf) # epochs to wait after fitness stops improving to stopself.possible_stop …

若依 ruoyi-vue 根据角色切换路由菜单权限 SAAS

后端根据角色查询相应的菜单(角色对应管理的系统) /*** 获取路由信息根据角色(系统类型)** return 路由信息*/GetMapping("getRoutersBySystemType")public AjaxResult getRoutersBySystemType(String systemType) {Lon…

2024最新版鸿蒙纯血原生应用开发教程文档丨学习ArkTS语言-基本语法

ArkTS是HarmonyOS的主要应用开发语言,在TypeScript基础上进行了扩展,保留了其基本风格,并通过增强静态检查和分析来提高程序的稳定性和性能。本教程将帮助开发者掌握ArkTS的核心功能、语法及最佳实践,以便高效地构建高性能移动应用…

使用插件 `vue2-water-marker`添加全局水印

使用插件 vue2-water-marker添加全局水印 效果图 1、安装插件 npm install vue2-water-marker --save2、全局注册 // main.js import Vue from vue import Vue2WaterMarker from vue2-water-markerVue.use(Vue2WaterMarker)3、在组件中使用 <template><div id&q…

docker安装etcd:docker离线安装etcd、docker在线安装etcd、etcd镜像下载、etcd配置详解、etcd常用命令、安装常见问题总结

官方网站 官方网址&#xff1a;etcd 二进制包下载&#xff1a;Install | etcd GitHub社区项目&#xff1a;etcd-io GitHub GitHub社区项目版本历史&#xff1a;Releases etcd-io/etcd GitHub 一、镜像下载 1、在线下载 在一台能连外网的linux上执行docker镜像拉取命令…

探索浮点数在内存中的存储(附带快速计算补码转十进制)

目录 一、浮点数在内存中的存储 1、常见的浮点数&#xff1a; 2、浮点数存储规则&#xff1a; 3、内存中无法精确存储&#xff1a; 4、移码与指数位E&#xff1a; 5、指数E的三种情况&#xff1a; 二、快速计算补码转十进制 1、第一种方法讨论&#xff1a; 2、第二种方…

第25周JavaSpringboot实战-电商项目 4.商品分类管理

商品分类模块开发笔记 模块功能概述 实现分类数据的 增删改查 功能核心难点&#xff1a; 分类的父子级目录结构递归实现多级分类查找列表展示顺序控制&#xff08;从父级向子级递归&#xff09; 接口说明 后台接口 1. 添加分类 请求地址: /admin/category/add 请求方法: …

【星云 Orbit-F4 开发板】03g. 按键玩法七:矩阵键盘单个触发

【星云 Orbit-F4 开发板】03g. 按键玩法七&#xff1a;矩阵键盘单个触发 引言 矩阵键盘是一种常见的输入设备&#xff0c;广泛应用于各种嵌入式系统中。通过矩阵键盘&#xff0c;用户可以通过按键输入字符或控制信号。本文将详细介绍如何使用STM32F407的GPIO引脚实现矩阵键盘的…

Milvus x DeepSeek 搭建低成本高精度 RAG 实战

为什么手握海量数据&#xff0c;却用不出真正的“智能”&#xff1f;要么 AI 模型学艺不精&#xff0c;答非所问&#xff1b;要么技术门槛太高&#xff0c;让普通开发者望而却步。现在&#xff0c;使用阿里云 Milvus 向量检索服务、DeepSeek 大模型和 PAI LangStudio 开发工具&…

每日一题——两数之和

两数之和 问题描述示例提示思路分析代码实现代码解析1. 哈希表结构体定义2. 初始化哈希表3. 释放哈希表内存4. 主函数 twoSum5. 返回结果复杂度分析 第二种解法代码功能概述代码详细注释1. 哈希表结构体定义2. 哈希表指针3. 查找函数4. 插入函数5. 两数之和函数 6. 主函数&…

2025年SCI1区TOP:真菌生长优化算法FGO,深度解析+性能实测

目录 1.摘要2.算法原理3.结果展示4.参考文献5.代码获取 1.摘要 本文提出了一种新型的自然启发元启发式算法——真菌生长优化算法&#xff08;FGO&#xff09;&#xff0c;灵感来源于真菌在自然界中的生长行为。真菌的生长行为包括菌丝生长、分枝和孢子萌发&#xff0c;菌丝生长…

穿越AI边界:深度集成DeepSeek API与云平台的实践之路

云边有个稻草人-CSDN博客 随着人工智能技术的日益发展&#xff0c;深度学习和自然语言处理&#xff08;NLP&#xff09;已经在很多领域得到了广泛的应用。DeepSeek作为一款领先的大型语言生成模型&#xff0c;凭借其强大的推理和生成能力&#xff0c;已经被越来越多的开发者和…

动态表头导出EasyExcel

在 Spring Boot 中结合 EasyExcel 实现动态表头导出&#xff08;无实体类&#xff0c;表头和字段&#xff08;前端传表名&#xff0c;字段值动态查询&#xff0c;返回List<Map<String,Object>>&#xff09;由前端传递&#xff09;可以通过以下步骤实现。以下是完整…

1 | 从零开始解密数据库:数据库基础概念

❤个人主页&#xff1a;折枝寄北的博客 ❤专栏位置&#xff1a;数据库专栏 目录 前言1. 数据&#xff08;data&#xff09;2. 数据库(DB)3. 数据库管理系统(DBMS)4. 数据库系统(DBS) 感谢您的阅读支持 前言 【前言】 在万物互联的数字时代&#xff0c;数据已成为驱动社会运转…

Web自动化之Selenium下Chrome与Edge的Webdriver常用Options参数

目录 引言 说明 Add_argument() 添加方式 常用参数 Add_experimental_option() 添加方式 常用方法 任务结束后仍然保持浏览器打开 禁用“Chrome 正受到自动测试软件的控制”提示 设置下载路径 禁用弹窗拦截 禁用图片加载 禁用 JavaScript 注意 引言 …

AI提示词的种类与适合的任务

以下是提示词的主要种类及其适用任务&#xff0c;基于大模型特性与最佳实践总结&#xff1a; 一、基础提示词 零样本提示&#xff08;Zero-shot Prompting&#xff09; 形式&#xff1a;直接输入任务指令&#xff0c;不提供示例&#xff08;如“翻译以下句子&#xff1a;Hello …

FTP 实验(ENSP模拟器实现)

目录 FTP 概述 FTP实验 FTP的报文交互 FTP 概述 FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09;是一种用于在网络上进行文件传输的标准协议。它允许用户在两台计算机之间上传和下载文件。 1、FTP采用客户端-服务器模型&#xff0c;客户端通过…

Windows前端开发IDE选型全攻略

Windows前端开发IDE选型全攻略 一、核心IDE对比矩阵 工具名称最新版本核心优势适用场景推荐指数引用来源VS Code2.3.5轻量级/海量插件/跨平台/Git深度集成全栈开发/中小型项目⭐⭐⭐⭐⭐14WebStorm2025.1智能提示/框架深度支持/企业级调试工具大型项目/专业前端团队⭐⭐⭐⭐47…

鸿蒙5.0实战案例:har和hsp的转换

往期推文全新看点&#xff08;文中附带全新鸿蒙5.0全栈学习笔录&#xff09; ✏️ 鸿蒙&#xff08;HarmonyOS&#xff09;北向开发知识点记录~ ✏️ 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…

简单易懂,解析Go语言中的struct结构体

目录 4. struct 结构体4.1 初始化4.2 内嵌字段4.3 可见性4.4 方法与函数4.4.1 区别4.4.2 闭包 4.5 Tag 字段标签4.5.1定义4.5.2 Tag规范4.5.3 Tag意义 4. struct 结构体 go的结构体类似于其他语言中的class&#xff0c;主要区别就是go的结构体没有继承这一概念&#xff0c;但可…