项目实训(一):项目基础框架与 FastAPI 后端创建
一、写在前面写在最开头处这是我的第一篇博客也是第一次正“试”的、有系统的、分工明确的做一个项目算是一个尝试吧也许接下来的开发过程是坎坷的、稚嫩的但我觉得这会是一次崭新的开始之后的内容将主要聚焦于我自己的开发思路包括但不限于技术实现、团队协作与个人反思。本项目的定位是一款面向初学开发者的VS Code 内嵌式代码安全复核与修复辅助插件。这个项目的目标并不是做一个企业级通用安全平台太大了也不是简单做一个“把代码扔给 AI 看看有没有问题”的聊天工具而是希望在真实编码环境中帮助用户发现代码中的常见安全风险理解漏洞为什么危险获得修复建议在上下文不足时逐步补充分析信息在正式开始写功能之前我先做了两件我自认为很重要的事明确整个项目的整体框架明确不同模块之间的接口和边界因为如果一开始只想着“先写点东西”最后很容易出现插件和后端接口对不上、分析逻辑到处乱写、后期升级时推倒重来、多人同时开发但很难对接头大…。所以我的思路是先把框架搭稳再逐步往里面填能力。因此这篇博客我主要记录两部分内容我对这个项目整体接口和框架的理解我如何从 0 开始搭建 FastAPI 后端基础框架这也是接下来我核心负责的部分二、目前定义的整体系统框架结合目前的讨论我把整个系统先理解成三层插件交互层VS Code Extension本地分析服务层Python FastAPI上下文增强与 AI 层现阶段我不想把结构搞得太复杂但这三层至少要先分清楚。1. 插件交互层VS Code Extension这一层运行在 VS Code 里负责用户真正看到和操作到的内容。它主要负责注册命令读取选中代码读取当前文件获取工作区路径调用本地分析服务展示分析结果在编辑器中高亮风险代码在 Problems 面板中列出问题在右侧解释面板中展示解释和修复建议一句话概括就是插件层负责“能用”和“好看”不负责真正的风险分析。2. 本地分析服务层Python FastAPI它的任务不是“讲解漏洞”而是先把候选风险找出来并输出基础证据链。这一层也就是我需要做的后续会逐步补进这些能力AST 解析规则检测source / sink 识别def-use 关系函数内污染传播分析taint analysis风险候选生成基础证据链输出注我的设计思路第一版不追求完整静态分析器先做“够用版程序分析链”先支持函数内、局部范围内的分析先把统一输入输出跑通也就是说不是一下子分析得多复杂而是先有能力把“哪里可能有风险”找出来。3. 上下文增强与 AI 层它不是从零开始找漏洞而是在已有候选风险和证据链基础上继续做渐进式上下文补全多轮分析流程控制AI 分析包构造语义复核漏洞解释生成修复建议生成我目前的理解是AI 在这里不是第一发现者而是“复核员 解释员 修复建议生成器”。这一点我觉得需要说清楚 因为如果把 AI 直接当成“万能分析器”最后这个项目很容易变成一个“把代码扔给模型聊一聊”的东西。但我们现在想做的其实是先用规则和程序分析找出候选风险再在这个基础上让 AI 做进一步解释和增强所以这层更像是“在已有结果基础上的智能增强”而不是“完全替代前面的分析”。三、为什么要先定义接口在最开始的这个阶段我越来越觉得先把接口定义清楚比马上写复杂逻辑更重要。原因主要有两个。1. 三个人协作必须靠接口我们三个人不可能等一个人全写完再开始。插件、后端、AI 增强模块必须并行推进而并行开发的前提就是插件知道该给后端传什么后端知道该返回什么AI 层知道该吃什么中间结果最终展示层知道该显示什么字段如果这些东西不先说清楚那后面很容易出现一种情况大家都在写东西但最后拼不起来感觉会很乱…。2. 后续升级不能老推倒重来因为我之后写从“函数内分析”升级到“跨函数 / 跨文件分析”很多地方都会出现这种考量吧我不希望整个系统被推倒重写。更理想的方式应该是输入接口尽量不变中间 schema 尽量不变某些分析模块增强某些搜索策略替换所以项目一开始就要先约定请求对象长什么样中间结果对象长什么样最终结果对象长什么样这样后续升级时尽量是“换模块、加模块”而不是“整套推翻”。四、当前设计的最小接口在项目刚开始的时候因为才刚开始不可能一上来就把所有字段设计得很清楚。但是插件和后端要能先对接上后端和后续分析模块能先传递基本结果插件能先把结果显示出来所以我这里设计了三类最小接口。1. 插件发给后端的请求对象我目前定义的最小请求信息包括mode分析模式selection/filelanguage代码语言如python/javascriptfile_path当前文件路径code当前选中代码或整个文件内容workspace_root项目根目录可选cursor_range起止行号可选这里我目前主要考虑以python和javascript为核心支持对象后面如果要扩语言再逐步往外扩。这个请求对象的核心目的很简单就是先解决一个最基本的问题插件到底要把什么信息交给后端。2. 后端输出的基础分析结果在当前阶段后端还不会直接返回很完整的漏洞解释而是先输出一份基础分析结果。这份结果主要回答三个问题这里可能是什么类型的风险风险大概出现在什么位置当前信息够不够继续判断所以我现在更倾向于先保留这些最基础的字段risk_type_candidate候选风险类型line_range风险大概对应的代码范围needs_more_context当前是否还需要更多上下文也就是说在项目刚起步时后端最重要的不是一下子把所有分析信息都做全而是先做到告诉后续模块哪里可能有问题现在还缺不缺更多信息。3. 最终输出给插件展示的结果插件最终要做的是把结果展示给用户所以它真正需要的是一份适合展示的结果对象。在当前这个阶段应该先把这部分控制得简单一点至少包括summary一句简短总结risk_level当前风险级别start_lineend_linereason简单原因说明这已经足够插件先实现弹出结果定位代码位置给出一句基本解释至于更完整的字段我觉得更适合放在后续阶段逐步加入。所以这一层目前的核心目标其实可以概括成一句话先让插件知道“怎么展示一个最基本的分析结果”。五、FastAPI 后端基础框架的搭建过程这一部分是我这次真正动手完成的内容。至于这里为什么选择Python FastAPI原因挺多的列举两个自动生成可交互的接口文档docs代码变了文档自动更新;自动参数校验不再赘述了后面项目进行会更加直观地看到下面带来基础中的基础版但感觉还是很重要吧所以还是写了下来。。。1. 创建后端目录我先在项目根目录下建立code-guard-tutor/ └─ backend/这是整个后端的工作区。后面所有服务启动、依赖安装、接口文件和分析代码都会放在这个目录下面。2. 创建虚拟环境我使用了 Python 自带的venv模块创建虚拟环境python-mvenv .venv对虚拟环境的理解给当前项目单独准备一个 Python 小环境避免和其他项目的依赖冲突。然后激活它Windows PowerShell 版.venv\Scripts\Activate.ps1激活成功后终端前出现(.venv)说明已经在这个虚拟环境下了注之后在其他终端运行也需要这个指令。3. 安装最小依赖后端只安装了三个最基础的依赖pipinstallfastapi uvicorn pydantic它们分别做什么fastapi后端框架uvicorn运行 FastAPI 的服务器pydantic定义和校验请求/响应数据格式安装完成后pip freezerequirements.txt生成依赖清单文件方便以后复现环境很常用的命令。4. 创建最小目录结构我现在先搭了这个最小结构backend/ ├─ app.py ├─ requirements.txt ├─ api/ │ └─ routes/ ├─ schemas/ └─ core/这些目录分别是是app.py后端启动入口api/routes/具体接口文件schemas/请求和响应的数据结构定义core/后续真正分析逻辑这个阶段先不往core/里写内容只先把位置占好。因为本次目的是把“服务框架”和“接口结构”搭起来。【截图预留 5后端最小目录结构截图】5. 编写最小入口app.py在app.py中先写了一个健康检查接口fromfastapiimportFastAPI appFastAPI(titleCodeGuard Tutor Backend)app.get(/health)defhealth():return{status:ok}这一段代码是验证服务能不能启动路由能不能生效浏览器能不能访问6. 启动后端服务运行uvicorn app:app--reloaduvicorn 是一个ASGI 服务器可以理解为 “FastAPI 应用的运行容器”前面的app是文件名app.py后面的app是文件里创建的FastAPI应用对象--reload表示代码改动后自动重启这也是FastAPI的优点之一这一步成功后浏览器访问http://127.0.0.1:8000/health返回说明后端基础框架已经活了。7. 增加分析接口/analyze仅有/health还不够因为插件真正会调用的是/analyze所以增加了backend/api/routes/analyze.py然后定义一个最小分析接口。在这个阶段我并不让它真正分析代码而只是让它先能接收请求并返回一个假结果。这里定义一个小的analyze.pyfromfastapiimportAPIRouter routerAPIRouter()router.post(/analyze)defanalyze():return{summary:Backend is alive,risk_level:suspicious}然后再在app.py中把这个路由注册进去fromfastapiimportFastAPIfromapi.routes.analyzeimportrouterasanalyze_router appFastAPI(titleCodeGuard Tutor Backend)app.include_router(analyze_router)app.get(/health)defhealth():return{status:ok}这里app.py 负责启动和注册analyze.py 负责具体分析接口打开http://127.0.0.1:8000/docs可以看到一个自动生成的网页接口文档也就是FastAPI 自带接口文档点开 /analyze点击 Try it out再点击 Execute就能测试想了想感觉这里还是要写详细一点1. Parameters参数区 这里显示 No parameters说明当前 /analyze 接口没有定义任何请求参数上面代码里 analyze() 函数是空参数 2. 操作按钮 Execute点击后会直接发送请求到 /analyze测试接口是否正常 Clear清空本次请求 / 响应的调试记录 3. Curl命令行调试示例 这是 FastAPI 自动生成的 curl 命令你可以复制到终端里直接运行效果和点 Execute 一样 -X POST指定请求方法 http://127.0.0.1:8000/analyze你的本地服务地址 -H accept: application/json告诉服务器要返回 JSON 格式 -d 请求体为空因为当前接口没参数 4. Request URL请求地址http://127.0.0.1:8000/analyze 5. Server response服务器响应 Code: 200表示请求成功 ✅ Response body响应内容是你在 analyze.py 里写的返回值 6. Response headers响应头 content-length: 56响应体的字节数 content-type: application/json告诉客户端返回的是 JSON 格式 date请求处理的时间 server: uvicorn说明服务是由 uvicorn 运行的和启动命令对应 7. Responses响应说明区FastAPI 会在这里根据你的代码逻辑自动推断出接口可能返回的所有响应类型8. 定义请求数据结构为了不让接口随便乱收数据我在backend/schemas/request_schema.py里定义了最小请求结构例如modelanguagefile_pathcodeworkspace_rootcursor_range这样插件以后发请求时就必须按这个格式来接口不容易乱。要意识到schema 不是额外工作而是协作基础。一个最小的请求对象定义如下fromtypingimportLiteral,OptionalfrompydanticimportBaseModelclassCursorRange(BaseModel):start_line:intend_line:intclassAnalysisRequest(BaseModel):mode:Literal[selection,file]language:strfile_path:strcode:strworkspace_root:Optional[str]Nonecursor_range:Optional[CursorRange]NoneLiteral[“selection”, “file”]表示 mode 只能是这两个值之一Optional[str] None表示这个字段可以不传有了这个结构以后后端接收插件请求时就更明确了它知道自己该收到什么字段也知道这些字段分别应该是什么类型。9. 接收这个 schemafromfastapiimportAPIRouterfromschemas.request_schemaimportAnalysisRequest routerAPIRouter()router.post(/analyze)defanalyze(req:AnalysisRequest):return{summary:Backend is alive,risk_level:suspicious,received_language:req.language,received_file:req.file_path,code_length:len(req.code)}注意(req: AnalysisRequest)表示这个接口接收的数据必须符合 AnalysisRequest 这个格式测试替换默认内容为以下测试数据可以直观看到返回结果六、我对当前后端基础框架的理解总结到目前为止我搭出来的还只是一个后端壳子它还没有真正的分析能力。但这个壳子已经具备了几个非常重要的基础。已经完成的后端目录独立虚拟环境独立依赖管理明确FastAPI 服务跑通健康检查接口可用分析接口预留请求 schema 定义好后续core/逻辑有位置可放还没完成的AST 解析source/sink 识别规则检测taint 分析风险候选生成AI 分析包构造七、下一步准备做什么基于现在这个基础框架我后面准备继续做两件事1. 继续完善插件基础框架让 VS Code 插件能够读取选中代码调用/analyze显示后端返回结果2. 在backend/core/中加入真正的分析逻辑从最简单的部分开始AST 解析规则检测source / sink 识别当前阶段的重点仍然不是“做满”而是先把结构搭稳再往里面填能力。八、结语最后总结一下吧本次主要记录了在项目初期对整体接口和框架的思考并详细介绍了 FastAPI 后端基础框架的搭建过程。获益良多。