全部笔记
18

API从入门到实践 · 2026-10-27 · 约 37 分钟

API从入门到精通02:从空文件写出自己的问候接口

作者: · 个人博客

从下载资料、用记事本做Python自检开始,创建隔离环境,逐行写hello,实际操作Swagger发送请求,并验证保存重载、停止重启和独立welcome练习。

在上一课,我们认识了接口方案,也操作过别人已经写好的程序。这一课换你来写:浏览器里填的“小明”,怎样交给 Python 函数,再把“你好,小明”送回来?

先让一个 hello 工作,再分别改变输入、内部函数名与返回规则,最后在同一应用增加 welcome。你会用实际请求分清入口、输入和处理规则;可选独立任务是保留原两个入口,自己增加 goodbye。本课不提前加入数据库或 POST。

回看第1课:接口地图与商品查询

本集的主线:把一段处理能力交给别人调用

名字从哪里输入、谁把它交给 Python、哪个位置决定回答、结果又怎样回到浏览器?这一课沿着同一次问候请求,把这四个位置接起来。

学完后,请用自己的代码或 AI 辅助实现,实际完成:启动 /hello → 发出带名字的请求 → 改一次输入或规则 → 增加 /welcome → 独立增加 /goodbye → 停止再启动,确认原接口与新增接口仍然可用。

为什么这次选择 Python 和 FastAPI

API 可以用不同语言实现。这次用 Python,是为了把参数、处理和返回紧凑地放在屏幕上解释;用 FastAPI,是为了先借助它生成的测试页发送请求,暂时不用另写网页。已有 JavaScript 基础的人,也可以用 Node.js 等路线实现同样的输入输出约定。这是本课的选择,不是语言使用量排名。

可以手写,也可以让 AI 辅助

逐行演示用来解释代码怎样工作;逐字手敲不是通过条件。你要能够说明需求、提供环境和已有代码、看懂关键改动,并用实际 URL、状态码和响应正文验证结果。AI 回答“完成”,不等于你的电脑上已经运行成功。完整提示词和独立实践已放入下载包的 course/reference。

下载本集跟做资料

第二集跟做资料(ZIP)

解压后有 course 文件夹,包含依赖清单、Python 阅读补课、完整指南和单独放置的参考答案。hello 中没有预写好的 first_api.py,留给你自己新建。包内不含 Python 安装程序、虚拟环境或在线服务,首次准备依赖需要联网。

下载文件名:hello-start-r09.zip;SHA-256:0d44ff45ad0e165aaada6d960881a8a0cef47de1e4d1454fda5ca390de5b4eaf。

每条命令输入完整后按一次回车,看到对应结果再继续。可以先完成当前步骤再继续阅读;配合视频学习时,暂停视频完成操作,再回到刚才暂停的位置。视频先讲代码怎样工作;要同步跟做,请先完成下面的准备,再回到“让代码运行”处启动。

A.下载、阅读和写文件

  1. 在第二集教程点击实际的“第二集跟做资料(ZIP)”入口。下载完成后,用浏览器下载记录的“在文件夹中显示”找到文件。
  2. 对 ZIP 选择 Windows 的“全部解压缩”,解压到自己选定的普通目录。不要在 ZIP 预览里运行。
  3. 打开解压后的 course,应看到 hello、reference、verification、basics、requirements.txt 和 README.md,共六项。hello 是自己写代码的位置;reference 供做完以后核对;basics 是 Python 阅读补课。
  4. 用 VS Code 的 File/文件 → Open Folder/打开文件夹,选择这份 course。在左侧 hello 上右键 → New File/新建文件,输入完整的 first_api.py,回车。已有这个文件,就打开核对并保存,不要重复新建或覆盖自己的进度。
  5. 按视频逐段写入下面的规则,按 Ctrl+S 保存。扩展名是 .py,不是 .py.txt。需要从头练习时,把原 ZIP 解压到另一个新目录,保留已有文件和环境。
from fastapi import FastAPI

app = FastAPI()

@app.get("/hello")
def hello(name: str = "同学"):
    return {"message": f"你好,{name}"}
写到这里解决什么问题
from fastapi import FastAPI从已安装的包中取出创建应用的工具
app = FastAPI()创建并命名应用对象
@app.get("/hello")登记 GET 与路径对应的处理函数
name: str = "同学"接收名字,没有提供参数时采用默认值
缩进后的 return返回问候字典,由框架形成 JSON 响应

编辑器可从 VS Code 官方 Windows 页面取得。安装编辑器不等于准备好了 Python;本课使用终端命令启动,不依赖编辑器的运行按钮。首次打开文件夹若出现信任提示,先核对来源,仅针对自己刚取得并检查的课程文件选择。

先用记事本读 Python 自检与补课

没有编辑器也能阅读,不需要先安装 Markdown 插件:

  1. 在解压后的 course 中进入 basics。
  2. 按 Windows 键,搜索并打开“记事本”。
  3. 在记事本按 Ctrl+O,找到自己这份 course/basics。将文件类型从“文本文档/文本文件(*.txt)”改成“所有文件(*.*)”,打开 Python阅读自检与补课.md。
  4. 阅读四题、解释和参考答案。井号、反引号和方括号是文字排版标记,不是要执行的命令。先看懂参数、默认值、return 与缩进即可继续,其余可以回看。
  5. 读完关闭阅读窗口,回到视频刚才暂停的位置。已经写好代码,就继续核对保存;已经准备好环境,就继续使用。不要因为看了补课,重新新建同名文件或从头准备环境。

已有 Markdown 阅读工具也可直接打开 course/basics/Python阅读自检与补课.md。包内 course/README.md 是这份完整跟做指南,也能用记事本打开。终端命令不在记事本中输入。

B.解释器、环境和依赖

B1.从自己的 course 打开命令窗口

用文件资源管理器打开 course,点击文件夹顶部地址栏,输入 powershell 并回车。这是文件夹地址栏,不是浏览器网址栏。在新打开的 PowerShell 逐条执行:

Get-Location
Get-ChildItem
py -3.12 --version
Test-Path .\.venv

前两条应对应自己的 course 和六项起点内容。版本检查须真正成功选中 Python 3.12;本课也允许已可用的 3.11。Test-Path 只判断目录是否存在,不证明环境可用。

B2.只选一条已经检查成功的路线

已成功的版本检查仅当 .venv 不存在时,用来创建的命令
py -3.12 --versionpy -3.12 -m venv .venv
py -3.11 --versionpy -3.11 -m venv .venv
pymanager exec -V:3.12 --versionpymanager exec -V:3.12 -m venv .venv

上表不是要连续执行的三条命令。只沿用自己已经检查成功的那一条,而且 Test-Path .\.venv 返回 False 才创建。创建结束后立即执行 $LASTEXITCODE,应为 0。

终端不认识 py,或没有可用的 3.11/3.12 时,先从 Python 官方 Windows 页面准备本课所选版本。已有可用版本就跳过安装,不卸载其他项目的 Python。使用当前 Python install manager 的具体路线见 Windows 官方文档。安装管理器后,仍从原来的 course 重新打开 PowerShell,再执行:

py install 3.12
py -3.12 --version

只有已经装好新管理器、但旧启动器占用了 py,使 py install 不被识别时,才用管理器独立入口:

pymanager install 3.12
pymanager exec -V:3.12 --version

若 pymanager 也不被识别,先确认管理器安装完成并重新打开 PowerShell,不假设每台电脑都有它。两种入口都失败时保留输出,停止在版本选择这一步。如果 py -0p 已列出目标版本,但简写选不到,先看下一节,不直接认定没有安装。

B3.本机列出带提供方标签的 Python 时

普通简写已经成功就跳过本节。需要排查时先看本机实际清单和帮助:

py -0p
py --help

只选择清单中实际存在的 3.11/3.12。如果帮助支持 -V:提供方/标签,把清单中的实际完整选择器用于 --version;成功以后,才沿用同一个选择器创建环境。提供方/标签 是说明位置,不能原样当命令执行。

教师这台电脑的一个选择器示例是:

py -V:Astral/CPython3.12.13 --version

这不是每台电脑都通用的选择器。**只有自己的清单也实际列出它、检查成功,而且 .venv 不存在时**,才对应使用:

py -V:Astral/CPython3.12.13 -m venv .venv

不要照抄教师的提供方标签或绝对路径。也可以将本机清单中目标 python.exe 的实际完整路径存入仅用于这一步的变量:

$selectedPython = Read-Host '粘贴本机清单中 Python 3.11/3.12 的完整 python.exe 路径,不带外层引号'
Test-Path -LiteralPath $selectedPython -PathType Leaf
& $selectedPython --version
$LASTEXITCODE

只有路径存在、版本检查成功、退出码为 0,且 .venv 不存在,才执行:

& $selectedPython -m venv .venv
$LASTEXITCODE

建好环境以后不再依赖这个变量,后续统一使用项目内环境路径。目录或版本不能确认时不创建,可把完整命令与输出交给 AI 协助解释。

B4.无论新建还是已有,都核对同一个环境

在 course 执行:

.\.venv\Scripts\python.exe --version
.\.venv\Scripts\python.exe -m pip --version

应为本课选定的 3.11/3.12;pip 的位置应在当前这份 course/.venv 中。解释器或 pip 不可用、版本或路径不对,就停下排查,不直接删除重建,也不换成系统 Python 往下做。

B5.安装与成功判断

在 course 执行下面这一条安装命令。终端自动折行,不表示要分成几条命令:

.\.venv\Scripts\python.exe -m pip install -r .\requirements.txt -c .\verification\constraints-windows-20261018.txt

等安装完整结束、普通提示符回来,立即检查:

$LASTEXITCODE

只有 0 才继续:

.\.venv\Scripts\python.exe -m pip check
$LASTEXITCODE

No broken requirements found. 且退出码为 0,才完成这一步。失败就保留完整报错与命令,按原因排查,不能只截一行成功输出,也不反复重建或卸载旧环境。已经完成安装并核对通过时,不必因为回看视频重复安装。

依赖清单和约束快照随包提供。创建、安装与运行使用同一份环境;直接使用解释器路径,不要求激活环境或修改 PowerShell 执行策略。

C.跟着实验,分清入口、输入与规则

C1.让代码运行

先确认 A 中的初始 hello 代码已保存。当前从 course 出发,进入 hello,核对自己的目录和文件,再执行完整命令:

Set-Location .\hello
Get-Location
Get-ChildItem
..\.venv\Scripts\python.exe -m uvicorn first_api:app --host 127.0.0.1 --port 8003 --reload

最后一条是一条命令。first_api 是文件名去掉 .py,app 是应用变量,.. 找上一层的课程环境。看到监听 127.0.0.1:8003 和 Application startup complete 后再访问。运行时没有普通提示符是正常的,保持这个窗口。

本机实验入口

先完成上面的准备并保存自己的代码,看到 Application startup complete 后再点击。保持服务命令窗口运行。下面是教程按本课端口、路径和参数预先准备的普通链接,访问点击者当前电脑的 8003 端口。127.0.0.1 指当前电脑自己。

链接在新标签页打开;保留本教程标签,每次核对结果后切回这里点下一条。完整目标写在链接中,先看清 /docs 与 /hello 的区别:

包内指南若用记事本阅读,这些链接会显示为排版文字。回到第二集教程的同名入口点击,或使用已有的 Markdown 阅读工具;不要在记事本里执行网址。

C2.测试页到底发了什么

  1. 在上面的“本机实验入口”点击“打开本机测试页 /docs”,核对打开了 Swagger UI;保留教程标签。
  2. 展开 GET /hello → Try it out → name 填“小明” → Execute。
  3. 核对本次 Request URL、实际使用的 GET 方法、Server response 中实际 Code 200,以及正文 {"message":"你好,小明"}。预先列出的文档响应不等于这次实际响应。

填名字只是准备,点 Execute 才发出问候请求。/docs 是测试工具页,下面的 Request URL 是它实际调用的接口。127.0.0.1 指当前电脑自己;本机没有启动服务,不能用它访问教师电脑。本集使用 8003,不要和第一集的 8004 混用。

C3.换一个入口工具,仍能调用

保持同一服务和代码运行,回到“本机实验入口”,点击“给小明打招呼”。本次链接完整目标是 http://127.0.0.1:8003/hello?name=小明,新页面正文应为 {"message":"你好,小明"}。

切回保留的教程标签,再点“给小红打招呼”。完整目标只把名字改成 http://127.0.0.1:8003/hello?name=小红,新页面正文应为 {"message":"你好,小红"}。

在这个例子里,点击普通链接就会发出 GET 请求:/hello 指定入口,? 后的 name 提供这次名字。没有使用 Swagger 输入框,服务仍按同一份规则回答。这是两条新请求。直接打开的 JSON 页没有显示状态码时,只据此核对链接目标与正文,不说已经观察到 200。需要状态时,在 Swagger 实际响应区或浏览器 Network 中查看。中文 URL 的百分号编码是正常显示形式。本例的普通链接 GET 做法不用于发送 POST。

C4.只改内部函数名

在自己同一份 first_api.py 中,只把 def hello 改成 def greet,其余保持原样:

@app.get("/hello")
def greet(name: str = "同学"):
    return {"message": f"你好,{name}"}
  1. 按 Ctrl+S 保存,等服务检测到变化,并出现新一轮 Application startup complete。
  2. 切回教程,在“本机实验入口”点击“打开本机测试页 /docs”,刷新实际文档。
  3. 按方法与路径找到 GET /hello,不要只按函数名或摘要找,摘要可能显示 Greet。
  4. Try it out → 填“小明” → Execute。核对仍请求 /hello,实际 200,正文 {"message":"你好,小明"}。

这说明本例的直接 GET 调用仍按登记的方法和路径工作。函数名也可能被其他 Python 代码引用,或影响默认文档摘要、OpenAPI operationId;不能由此推成所有名字都能随便改、所有客户端契约都不变。本课没有生成 SDK。

C5.固定请求,只改返回规则

保持 def greet、/hello 与默认值不变,只把 return 中的“你好”改成“早上好”:

    return {"message": f"早上好,{name}"}

保存、等重载完成,再用 Swagger 实际发出 GET /hello?name=小明。同一输入这次应返回 {"message":"早上好,小明"},实际状态为 200。这是服务改了规则,与调用方换输入是两件事。

实验后明确恢复初始 hello:def greet 改回 def hello,“早上好”改回“你好”,默认值仍为“同学”。保存、等重载完成,接着在同一应用继续,不换目录、不重建环境。下一组双入口对照会实际核对恢复后的 hello。

C6.在同一个应用新增 welcome

保留原 hello,在同一个 app 下逐段新增:

@app.get("/welcome")
def welcome(name: str = "新朋友"):
    return {"message": f"欢迎你,{name}"}

保存、等重载完成,切回教程,在“本机实验入口”点击“打开本机测试页 /docs”,刷新实际文档,让新增入口出现。分别展开对应路由,点 Try it out,填同一个名字“小明”,点 Execute,对照每次请求与实际响应:

方法完整请求 URL预期状态预期 JSON 正文
GEThttp://127.0.0.1:8003/hello?name=小明200{"message":"你好,小明"}
GEThttp://127.0.0.1:8003/welcome?name=小明200{"message":"欢迎你,小明"}

这两条都要实际发出,核对本次 URL、Code 与正文:既确认新增入口可用,也确认原 hello 已恢复。welcome 是课堂示范。完成以后,可对照包内 course/reference/two_routes.py;保持自己的启动位置仍为 course/hello,启动模块仍为 first_api:app。

C7.默认值与空字符串

在初始 hello 或课堂完成态下,可用下面的精确 URL 补充检查:

方法完整请求 URL预期状态预期 JSON 正文
GEThttp://127.0.0.1:8003/hello200{"message":"你好,同学"}
GEThttp://127.0.0.1:8003/hello?name=200{"message":"你好,"}
GEThttp://127.0.0.1:8003/welcome200{"message":"欢迎你,新朋友"}

第三条需要已经完成 welcome。没有提供参数才用默认值;空字符串不是省略。 省略参数以完整 URL 中没有 ?name 证明,不把清空 Swagger 输入框当成必然省略。表格是预期结果,要实际发送再核对;只在 JSON 页面看到正文时,不把预期状态当成已经观察到的状态。

D.可选独立迁移:自己加 goodbye

这题没有在视频中逐段演示答案。前提是课堂 hello 与 welcome 都已可用。先保持服务运行,完成以下要求:

  • 保留原两个入口,在同一个 app 新增 GET /goodbye。
  • 接收查询参数 name,没有提供时使用“访客”。
  • JSON 字段叫 message,内容为“再见,”加本次名字。
  • 自己完成后保存、等重载、刷新 /docs,再逐条验收;期间不要先停服务。
方法完整请求 URL预期状态预期 JSON 正文
GEThttp://127.0.0.1:8003/goodbye?name=小林200{"message":"再见,小林"}
GEThttp://127.0.0.1:8003/goodbye200{"message":"再见,访客"}
GEThttp://127.0.0.1:8003/hello?name=小明200{"message":"你好,小明"}
GEThttp://127.0.0.1:8003/welcome?name=小明200{"message":"欢迎你,小明"}

明确名字的 goodbye、原 hello 和 welcome,可以分别在 Swagger 对应路由点 Try it out → 输入名字 → Execute,核对本次 URL、实际 200 与 JSON。默认 goodbye 用完整的无 ?name 地址证明省略;如需同时观察状态,打开 F12 → Network/网络,再访问这个完整地址,核对该请求的状态与正文。不要向开发者工具粘贴来历不明的代码。

保留自己的代码与保存后重载就绪的画面、各次实际请求和响应。还要用自己的话解释哪行登记入口、哪行接输入、哪行返回结果,以及保存、重载、刷新文档分别解决什么问题。做完再看包内 course/reference/goodbye_answer.py,不要先复制答案覆盖自己的文件。只观看答案不计独立完成,教师程序测试也不能替代学员独立完成。

E.停止与下次从原处恢复

完成课堂或独立练习验收以后,在运行服务的原 PowerShell 窗口按一次 Ctrl+C。等待正常关闭日志与普通提示符,再关闭窗口。

下次在文件资源管理器打开自己原来的 course/hello,从这个文件夹顶部地址栏输入 powershell 并回车,然后逐条执行:

Get-Location
Get-ChildItem
..\.venv\Scripts\python.exe -m uvicorn first_api:app --host 127.0.0.1 --port 8003 --reload

前两条确认仍是原来的 course/hello,并且有自己的 first_api.py。已经在 hello 就不要再进入一层 hello。沿用原环境和原文件,不新建同名文件、不重新安装。

等监听与 Application startup complete 出现,切回本教程,在“本机实验入口”点击“打开本机测试页 /docs”,刷新实际文档。课堂完成态复验 C6 的两条请求;做过独立任务的,再复验 D 的四条请求。 每条都核对新的实际响应,确认恢复后原接口和新增入口都还在。若上次只完成了初始 hello,就先验收 hello,再继续课堂,不要求尚未编写的入口已存在。

F.卡住时按同一步排查

现象先核对视频回到哪里
下载、编辑器或材料阅读未就绪A 的实际文件与官方入口;已有文件只核对保存当前准备处;完成后回原暂停处
Python 版本或选择器异常B2/B3 的本机清单、版本、帮助与完整输出,不照抄教师标签启动代码前的准备处
环境或安装异常B4/B5;保留完整命令与报错,不盲目重建或改全局配置启动代码前的准备处
找不到模块当前目录是否为自己的 course/hello,文件名与 app 是否对应命令启动服务处
端口占用核对占用者与报错,不结束不明进程启动服务处
hello 有 JSON,docs 白屏按下一节检查接口描述与 JS/CSS 的实际错误打开测试页处
改代码仍是旧结果是否同一文件、已保存、重载完成、新发了请求,当前规则是否已恢复对应的改名或改规则实验
welcome/goodbye 不出现保存并等重载后刷新 docs,核对路由是否实际登记新增入口处或独立任务

接口能返回,但 /docs 白屏或一直加载

保持服务运行,先点击本机 hello 接口(http://127.0.0.1:8003/hello)。能看到问候 JSON 而 /docs 仍空白,只说明接口能响应、文档页面另有问题,不能直接断定 CDN 故障。保持服务和环境,依次检查:

  1. 在“本机实验入口”点击“打开本机测试页 /docs”,切到实际测试页后按 F12;打不开时用 Ctrl+Shift+I。
  2. 点 Network/网络,再按 Ctrl+R 刷新页面。
  3. 查看 swagger-ui-bundle.js、swagger-ui.css 和 openapi.json 是否加载失败,记录失败网址、状态或错误文字;这三者的失败原因不一定相同。也可点击本机接口描述(http://127.0.0.1:8003/openapi.json),核对接口描述能否取得。
  4. 点 Console/控制台,保留相关报错截图或脱敏文字。不要向控制台粘贴来历不明的代码。
  5. 原因未确认时不重建环境、不关闭浏览器安全检查。解决后回到“本机实验入口”点击“打开本机测试页 /docs”,刷新实际测试页,展开 GET /hello → Try it out → 填“小明” → Execute,核对本次 URL、实际 200 和正文;已经写好 welcome/goodbye 的再按原验收表复验。

FastAPI 默认文档页会从外部 CDN 加载部分 JS/CSS,这些资源失败时接口仍可能正常。官方支持由应用自己提供静态资源,但本包没有附带已验证的离线文档版本。可以把官方文档资源方案交给 AI 对照实际错误,不临时改主线代码猜测修复。

给 AI 的排查说明

我在 Windows PowerShell 跟做问候 API,卡在【版本选择/创建环境/安装/启动/请求/重载】。当前目录是【实际目录】,Python 版本是【实际输出】,完整命令是【命令】,完整错误是【脱敏文字】。请先定位失败环节,给一个最小修复,再告诉我如何在同一步复验。不要先清空已有环境,不要结束不明进程,不要跳过失败往下做。

解决后回到原暂停处继续。截图不包含私人凭据或无关电脑内容。你应当能够指出自己的代码、解释入口/输入/返回值,发出新请求并对照新响应;只看到文件、启动日志或一份参考答案,还不能说明已经学会。

AI协作:可直接修改后使用的提示词

你可以自己写代码,也可以让 AI 辅助。需要自己理解接口的输入、处理与输出,并实际运行和核对。课堂首先读懂 /hello,AI示例的具体执行记录以本集视频及说明为准。

定义需求

先说清:谁会调用、做什么、输入什么、返回什么,以及怎样算符合要求。只有自己临时使用的函数可以直接运行;需要其他调用方按约定使用能力时,再考虑接口。

从空文件实现 hello

我正在学习最小本机API。Windows,Python3.12,FastAPI项目course,
虚拟环境course/.venv,代码放course/hello/first_api.py。
请先确认现有文件和环境;我没提供的信息先问清。
实现GET /hello,name为字符串,省略时用“同学”,明确空串时保留空串;
成功返回200和JSON,例如name=小华得到 {"message":"你好,小华"}。
先复述输入输出约定,给最小实现并解释入口、参数、返回各在哪里。
告诉我代码放哪里、在什么目录执行哪些完整PowerShell命令、
如何判断服务启动、如何用测试页发请求并核对本次状态和正文。
沿用已有环境,不增加数据库、登录或部署。
没有本机执行能力时,把结果写成预期,不宣称已经运行通过。

独立新增 goodbye

这是我现有的first_api.py:【贴入当前代码】。
保留/hello和/welcome,在同一个app中最小新增GET /goodbye。
查询参数name省略时使用“访客”,返回JSON的message为“再见,”加本次名字。
不另建服务,不改变原接口,不重新安装环境。
解释关键改动,给出保存、重载和验证步骤。
验收:/goodbye?name=小华应为200和 {"message":"再见,小华"};
/goodbye应为200和 {"message":"再见,访客"};
原/hello与/welcome仍按原规则返回。
没有实际执行的检查明确标注为预期,等我提供实际输出后再判断。

带证据反馈错误

目标:【接口约定】。我做到【步骤】,当前目录【目录】,
Python/环境信息【实际输出】,执行命令或Request URL【完整内容】,
预期【内容】,实际状态/正文/报错【原文】,相关代码【代码】。
请先解释证据指向哪个环节,给最小检查和修正,再重跑原验收。
缺少证据时明确告诉我需要哪项,不直接重写整个项目。

网页聊天AI通常看不到你本机的127.0.0.1,需要你实际运行并提供结果。带本机工具的AI助手也应区分已经执行的结果与预期。可以复制这些提示词,但应读懂其中自己的需求和验收条件。

视频实际发送给 AI 的提示词

这段是本集 CLI 演示实际发送的文本,示范只让 AI 返回建议,不让它操作电脑;随后由本机实际运行和请求验收。普通聊天 AI 可先使用上一节的通用提示词。

这是一个真实 Windows 本机 API 教程的 AI 协作示范。请只根据下面的约定返回结果,不调用任何工具,不读文件,不执行命令,不访问网络,不改文件,也不要声称已经运行通过。

我想让本机浏览器调用一段问候处理功能。当前已准备好 Windows、Python 3.12,以及本课既有 FastAPI/Uvicorn 环境;course/hello/first_api.py 是空文件。请从这个空文件实现最小的 GET /hello:
- 查询参数 name 是字符串;未提供时使用“同学”;提供空字符串时保留空字符串。
- 返回 JSON {"message":"你好,<本次名字>"},成功状态 200。
- 使用一个 FastAPI app;只实现 /hello,不添加 /welcome 或 /goodbye(它们留给后续迁移练习),不新增依赖、数据库、登录、前端或部署。

先用简短中文复述输入输出约定,解释为何在这里使用 Python、FastAPI 与 Uvicorn,以及代码的哪一处登记路径、接收输入、决定回答。返回完整可保存的 first_api.py;code字段只含Python源码,不含Markdown围栏。

运行说明面向学员的 course/hello 目录,虚拟环境为 course/.venv;给完整 PowerShell 启动命令,使用本机127.0.0.1:8003。启动前确认8003无其他服务占用,看到Application startup complete才发请求;不要自行启动、停用或替换服务。若学习者尚未完成环境准备,应回到教程准备段,不要把给出的命令当作安装已完成的证据。

验收预期(尚未实测):
/hello?name=小华 -> 200 和 {"message":"你好,小华"}
/hello -> 200 和 {"message":"你好,同学"}
/hello?name= -> 200 和 {"message":"你好,"}
用本次Request URL、状态和响应正文核对;不要读旧结果。说明网页填入参数与点击Execute发出请求是两步。相同约定也能交给聊天AI,但网页AI不能直接访问学习者自己的127.0.0.1,仍须本机运行验证。

只返回符合响应JSON schema的对象。execution_claim固定为“未执行;以上请求结果是预期,须本机验证”。不要把本回复当成真实请求回执。

该次 CLI 调用同时约束了以下响应结构,字段中“未执行”是当次生成回复的边界说明,不代表后续本机验证没有进行。

{
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "contract": {
      "type": "string"
    },
    "code": {
      "type": "string"
    },
    "explanation": {
      "type": "string"
    },
    "run_instructions": {
      "type": "string"
    },
    "execution_claim": {
      "type": "string",
      "enum": [
        "未执行;以上请求结果是预期,须本机验证"
      ]
    }
  },
  "required": [
    "contract",
    "code",
    "explanation",
    "run_instructions",
    "execution_claim"
  ]
}

第二集独立实践清单

先完成课堂 /hello 与 /welcome,保留现有服务环境。然后独立增加 /goodbye,允许手写或使用AI辅助。参考代码另见 goodbye_answer.py;先尝试、后参考。

  1. 说清新入口的方法、路径、参数、默认值与返回。
  2. 完成最小实现,保存并等待服务重载。
  3. 发送 /goodbye?name=小华,核对本次实际200及 {"message":"再见,小华"}。
  4. 发送不带name的 /goodbye,核对实际200及 {"message":"再见,访客"}。
  5. 再请求原/hello?name=小明与/welcome?name=小明,确认原功能保留。
  6. 停止服务后,用同一个项目和环境重新启动,再发请求验证。

请解释:输入由哪里接收、哪一处决定输出、为什么选GET、调用方需要知道内部函数名吗?

使用AI时,把相关代码、环境和约定提供给它,判断修改是否符合要求。不能只凭AI说“完成”或截图与老师一致来判断;也不要求逐字手敲代码。