三、FastAPI :POST 请求、用户接口设计与 Requests 测试

目录

1、前置知识

1.1、什么是HTTP请求方式

1.2、GET和POST请求方式

1、GET:查询数据("查")

2、POST:提交数据("增/提交")

3、核心区别

4、注意点

2、POST请求

2.1、核心概念

[2.2、基础示例:简单 POST 接口](#2.2、基础示例:简单 POST 接口)

1、代码实现

2、运行与测试

3、关键说明

3、request对象

4、基于FastAPI的用户接口设计与爬虫测试实践

4.1、技术栈选择

4.2、接口服务设计与实现

[1. 基础配置与数据结构](#1. 基础配置与数据结构)

[2. 核心验证逻辑](#2. 核心验证逻辑)

[3. 接口实现](#3. 接口实现)

[(1)注册接口 /user/register](#(1)注册接口 /user/register)

[(2)登录接口 /user/login](#(2)登录接口 /user/login)

[(3)信息查看接口 /user/logout](#(3)信息查看接口 /user/logout)

[4. 服务启动配置](#4. 服务启动配置)

4.3、接口测试脚本开发(基于requests)


1、前置知识

1.1、什么是HTTP请求方式

HTTP 请求方式(也叫 "HTTP 方法")是客户端(浏览器、App、Postman 等)向服务器发送请求时,附带的 "操作指令"

类比:你去银行办理业务,会先告诉柜员 "我要查余额""我要存钱""我要改手机号""我要注销账户"------ 这些指令就对应 HTTP 的 4 种核心请求方式,服务器根据指令执行不同操作。

核心原则:

  • 每种请求方式都有明确的 "业务语义",不能混用;
  • 服务器会根据 "路径 + 请求方式" 识别唯一接口(比如GET /user/1POST /user/1是两个不同接口)。

请求方式:

  • **GET:**查数据(无请求体,用路径 / 查询参数);
  • **POST:**创数据(有请求体,传复杂 / 敏感数据);
  • **PUT:**改数据(有请求体,全量覆盖);
  • **DELETE:**删数据(用路径参数传标识);

1.2、GET和POST请求方式

仅需掌握的 2 种核心请求方式(GET/POST)

在实际开发中,最常用的 HTTP 请求方式只有 2 种 ------GET(查询)POST(提交),完全能覆盖大部分业务场景(比如查询数据、用户注册、提交表单等)。

1、GET:查询数据("查")

核心作用

从服务器"获取"数据,不会修改服务器上的任何内容(只读操作)。

数据传递方式

通过 URL路径查询参数 传参(数据会暴露在URL中)。

适用场景

  • 商品列表查询、用户详情查询、搜索功能;
  • 不需要提交复杂/敏感数据的场景。
  • 路径传参或查询参数

2、POST:提交数据("增/提交")

核心作用

向服务器"提交"数据,通常用于创建新资源(比如注册用户)或提交表单(比如登录、下单)。

数据传递方式

通过 请求体 传参(数据隐藏在HTTP请求中,不暴露在URL里)。

适用场景

  • 用户注册、登录、提交订单;
  • 传递密码、多字段表单、复杂数据(比如嵌套信息)等敏感/复杂内容。

3、核心区别

|------|-------------|----------------|
| 对比维度 | GET(查) | POST(提交) |
| 核心作用 | 从服务器拿数据(只读) | 向服务器送数据(修改/创建) |
| 数据位置 | 暴露在URL中 | 隐藏在请求体中 |
| 敏感数据 | 不适合(URL暴露) | 适合(隐藏安全) |

**GET:**URL 传数据,公开、幂等、有大小限制,适合获取数据;

**POST:**请求体传数据,私密、非幂等、无大小限制,适合提交数据。

4、注意点

  1. GET方法不能带请求体(HTTP规范),想传请求体就用POST;
  2. 密码、手机号等敏感数据,必须用POST(请求体)传递,不能用GET;
  3. 接口标识是"路径+请求方式":GET /usersPOST /users 是两个不同接口,不会冲突。
  4. 通过浏览器地址栏只能访问使用GET方法的接口

2、POST请求

2.1、核心概念

  • POST 方法 :用于向服务器提交数据(如表单提交、创建资源),数据放在请求体(而非 URL 中),支持大量数据传输,更安全。
  • JSON 响应 :FastAPI 会自动将 Python 字典/列表序列化为 JSON 格式,响应头默认设为 application/json(无需手动配置)。
  • 请求体:POST 请求的核心数据载体,FastAPI 优先解析 JSON 格式的请求体。

2.2、基础示例:简单 POST 接口

1、代码实现

创建文件 main.py

python 复制代码
from fastapi import FastAPI

# 初始化 FastAPI 应用
app = FastAPI()

# 定义 POST 接口:路径为 /add
@app.post("/add")
def add_numbers(data: dict):  # data 接收 JSON 请求体(自动解析为 Python 字典)
    # 从请求体中获取参数(需自行处理参数缺失/类型错误)
    a = data.get("a")
    b = data.get("b")
    
    # 简单校验参数
    if not (isinstance(a, (int, float)) and isinstance(b, (int, float))):
        return {"code": 400, "message": "参数 a/b 必须是数字", "data": None}
    
    # 业务逻辑:两数相加
    result = a + b
    
    # 返回 JSON(直接返回字典,FastAPI 自动序列化)
    return {
        "code": 200,
        "message": "成功",
        "data": {"sum": result}
    }

2、运行与测试

  1. 启动服务器:
bash 复制代码
uvicorn main:app --reload
  1. 访问调试界面:浏览器打开 **http://127.0.0.1:8000/docs**(FastAPI 自动生成的 Swagger UI)。
  2. 测试步骤:
  3. 找到 /add****接口 ,点击Try it out
  • 输入 JSON 请求体(示例):

    {"a": 10, "b": 20}

  • 点击Execute

  • 查看响应结果(JSON 格式):

3、关键说明

  • 请求体解析data: dict 表示接收 JSON 格式的请求体,FastAPI 自动将 JSON 字符串转为 Python 字典。
  • JSON 响应 :返回值为 Python 字典时,FastAPI 自动设置响应头 Content-Type: application/json,并序列化字典为 JSON 字符串。
  • 手动校验问题:上述代码需手动校验参数类型/缺失,不够优雅------下一节将用 Pydantic 模型解决。

3、request对象

在实际开发过程中,有些时候我们需要通过Request对象直接获取⼀些信息,如:我们希望获取客户端的

IP等信息,此时我们在路由操作函数中直接定义类型为Request的对象参数,就可以在代码中使⽤

Request对象进⾏数据的获取。

假设在路由函数中定义了request:Request,那么该对象可以获取到哪些信息呢?

|------------------------|-------------------------------|
| 操作 | 说明 |
| request.client.host | 客户端连接的host |
| request.client.port | 客户端连接的端口号 |
| request.method | 请求方法 |
| request.base_url | 请求路径(注:通常base_url指请求的基础URL) |
| request.headers | 请求头信息 |
| request.cookies | 请求携带的Cookie |
| request.url | 完整请求URL |
| request.url.components | URL的各组成部分 |
| request.url.scheme | 请求使用的协议(如http/https) |
| request.url.hostname | 请求的host地址 |
| request.url.port | 请求的端口号 |
| request.url.path | 请求的路径部分 |
| request.url.query | 请求的URL查询参数 |
| request.path_params | 请求的路径参数(如/user/{id}中的id) |
| request.query_params | 请求的URL查询参数 |
| request.form() | 读取请求中的表单数据 |
| request.json() | 解析请求中的JSON数据 |
| request.body() | 读取原始请求体(字节类型) |

4、基于FastAPI的用户接口设计与爬虫测试实践

在Web开发中,接口是前后端交互的核心,而接口测试则是保障服务稳定性的关键环节。本文将通过一个简单的用户注册登录系统为例,介绍如何使用FastAPI快速搭建接口服务,并结合Python爬虫技术(requests库)进行接口测试,完整展示从接口开发到功能验证的全过程。

4.1、技术栈选择

本次实践涉及的核心技术如下:

  • FastAPI:一款高性能的Python Web框架,支持自动生成API文档,便于快速开发RESTful接口
  • requests:Python中最常用的HTTP请求库,可模拟浏览器发送请求,常用于接口测试和爬虫开发
  • 正则表达式:用于对用户名和密码进行格式验证
  • uvicorn:异步ASGI服务器,用于运行FastAPI应用

4.2、接口服务设计与实现

我们首先搭建一个包含用户注册、登录和信息查看功能的接口服务,核心代码如下:

1. 基础配置与数据结构

python 复制代码
import uvicorn
from fastapi import FastAPI, Request
import re

# 实例化FastAPI应用(注意:原代码缺失此行,实际开发需补充)
app = FastAPI()

# 模拟用户数据库(实际项目中应使用数据库存储)
user_datas = [
    {
        "username": "admin123",
        "password": "admin_123",
    }
]

2. 核心验证逻辑

为保证用户信息规范性,我们设计了用户名和密码的验证规则:

  • 用户名长度需大于6位
  • 密码需同时包含数字、字母、下划线,且长度至少9位
python 复制代码
def judgment(username, password):
    """验证用户名和密码格式是否符合要求"""
    # 密码正则:包含数字(?=.*\d)、字母(?=.*[a-zA-Z])、下划线(?=.*_),总长度9位以上
    if len(username) > 6 and re.match(r'^(?=.*\d)(?=.*[a-zA-Z])(?=.*_)[a-zA-Z0-9_]{9,}$', password):
        return 1  # 验证通过
    else:
        return 0  # 验证失败

3. 接口实现

(1)注册接口 /user/register

功能:接收用户名和密码,验证格式并检查用户名唯一性,成功则添加到用户列表

python 复制代码
@app.post('/user/register')
def register(request: Request):
    # query_params 是 Request 对象的属性,用于获取 URL 中的查询参数(键值对形式)
    username = request.query_params['username']
    password = request.query_params['password']
    
    # 检查用户名是否重复
    for user in user_datas:
        if user['username'] == username:
            return {"result": "注册失败:用户名重复"}
    
    # 验证格式并注册
    if judgment(username, password):
        user_datas.append({"username": username, "password": password})
        return {"result": f"注册成功:{username}成功注册"}
    else:
        return {"result": "注册失败:注册的用户名和密码未满足要求"}
(2)登录接口 /user/login

功能:验证用户凭据,成功则返回登录信息,失败则提示错误原因

python 复制代码
@app.post('/user/login')
def login(request: Request):
    username = request.query_params['username']
    password = request.query_params['password']
    
    if judgment(username, password):
        for user in user_datas:
            if user['username'] == username and user['password'] == password:
                return {'result': f"登录成功:{username}欢迎"}
        return {"result": "登录失败:用户名或密码错误"}
    else:
        return {'result': '登录失败:用户名或密码输入不正确'}
(3)信息查看接口 /user/logout

功能:返回当前系统中所有用户信息

python 复制代码
@app.get('/user/logout')
def logout():
    return {"massage": f"{user_datas}"}

4. 服务启动配置

python 复制代码
if __name__ == '__main__':
    # 启动uvicorn服务器,监听本地8000端口
    uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)

4.3、接口测试脚本开发(基于requests)

为验证接口功能,我们使用requests库开发一个交互式测试脚本,模拟用户操作流程:

测试脚本核心逻辑:

python 复制代码
# 导入 requests 库:用于发送 HTTP 请求(与 FastAPI 后端接口通信)
import requests

# 定义后端接口 URL 列表:按顺序对应 注册、登录、退出 接口
# 注意:原代码中 "查看" 功能调用的是 logout 接口(URLs[2]),存在逻辑不一致,后续需修正
urls = [
    'http://127.0.0.1:8000/user/register',  # 索引0:用户注册接口
    'http://127.0.0.1:8000/user/login',     # 索引1:用户登录接口
    'http://127.0.0.1:8000/user/logout',    # 索引2:用户退出接口(原代码误用于"查看"功能)
]

# 无限循环:持续接收用户操作,直到用户选择"4、退出"
while True:
    # 显示操作菜单,获取用户输入(strip() 去除输入前后空格,避免误触发)
    user_input = input('1、注册\n2、登录\n3、查看\n4、退出\n请输入你要进行的操作:').strip()

    # 分支1:用户选择"1、注册"
    if user_input == '1':
        # 接收用户输入的用户名和密码(用于注册)
        user = input("用户名:").strip()
        password = input("密码:").strip()
        
        # 发送 POST 请求到注册接口:
        # 注意:这里用 params 传递参数(参数会拼在 URL 上),不符合接口规范!
        # 推荐改为 json 参数(JSON 格式请求体):json={"username":user,"password":password}
        res = requests.post(
            url=urls[0],  # 目标接口:注册接口
            params={"username": user, "password": password}  # 传递注册参数(URL参数方式,不推荐)
        )
        
        # 解析响应结果:后端返回 JSON 格式,用 json() 转为 Python 字典
        result = res.json()
        
        # 打印响应中的 "result" 字段(假设后端返回格式包含该字段)
        print(f"注册结果:{result['result']}")

    # 分支2:用户选择"2、登录"
    elif user_input == '2':
        # 接收用户输入的用户名和密码(用于登录)
        user = input("用户名:").strip()
        password = input("密码:").strip()
        
        # 发送 POST 请求到登录接口:
        # 同样问题:用 params 传递参数(URL参数),不推荐,应改为 json 参数
        res = requests.post(
            url=urls[1],  # 目标接口:登录接口
            params={"username": user, "password": password}  # 传递登录参数(URL参数方式,不推荐)
        )
        
        # 解析 JSON 响应
        result = res.json()
        
        # 打印登录结果(后端返回的 "result" 字段)
        print(f"登录结果:{result['result']}")

    # 分支3:用户选择"3、查看"
    elif user_input == '3':
        # 发送 GET 请求:
        # 关键问题:原代码调用的是 logout 接口(URLs[2]),与"查看"功能不匹配!
        # 需修正为专门的查看接口(如 'http://127.0.0.1:8000/user/list')
        res = requests.get(url=urls[2])  # 错误:用退出接口实现查看功能,逻辑矛盾
        
        # 解析 JSON 响应
        result = res.json()
        
        # 打印响应中的 "massage" 字段:注意拼写错误(应为 "message"),需与后端返回字段一致
        print(f"查看结果:{result['massage']}")

    # 分支4:用户选择"4、退出"
    elif user_input == '4':
        print("退出程序...")
        break  # 终止无限循环,退出程序

    # 其他输入:无效操作
    else:
        print("输入的操作错误,请重新输入(仅支持 1-4)!")

通过本次实践,我们完整走通了"接口开发→功能测试"的流程。FastAPI的高效开发特性与requests的便捷请求能力相结合,为小型项目的接口验证提供了简单实用的解决方案。

相关推荐
CM莫问1 小时前
详解机器学习经典模型(原理及应用)——岭回归
人工智能·python·算法·机器学习·回归
SunnyRivers1 小时前
Python打包指南:编写你的pyproject.toml
python·打包·toml
计算机毕设小月哥2 小时前
【Hadoop+Spark+python毕设】中式早餐店订单数据分析与可视化系统、计算机毕业设计、包括数据爬取、数据分析、数据可视化
后端·python
n***26562 小时前
Python连接SQL SEVER数据库全流程
数据库·python·sql
β添砖java2 小时前
python第一阶段第六章python数据容器
开发语言·python
o***36932 小时前
python爬虫——爬取全年天气数据并做可视化分析
开发语言·爬虫·python
q***31142 小时前
【JAVA进阶篇教学】第十二篇:Java中ReentrantReadWriteLock锁讲解
java·数据库·python
时尚IT男3 小时前
Python 魔术方法详解:掌握面向对象编程的精髓
开发语言·python
找了一圈尾巴3 小时前
Python 学习-深入理解 Python 进程、线程与协程(下)
开发语言·python·学习