做门窗生意进哪个网站dede分类信息网站
2026/4/18 2:41:49 网站建设 项目流程
做门窗生意进哪个网站,dede分类信息网站,wordpress 调取缩略图,企业网站黄页怎么做GLM-4.7-Flash实战教程#xff1a;FastAPI封装GLM-4.7-Flash API并添加鉴权中间件 1. 为什么需要自己封装API#xff1f;原生vLLM够用吗#xff1f; 你可能已经注意到#xff0c;CSDN星图镜像里预装的GLM-4.7-Flash服务自带OpenAI兼容接口#xff08;http://127.0.0.1:8…GLM-4.7-Flash实战教程FastAPI封装GLM-4.7-Flash API并添加鉴权中间件1. 为什么需要自己封装API原生vLLM够用吗你可能已经注意到CSDN星图镜像里预装的GLM-4.7-Flash服务自带OpenAI兼容接口http://127.0.0.1:8000/v1/chat/completions和Swagger文档/docs开箱即用连Web界面都配好了。那为什么还要多此一举用FastAPI再包一层答案很实在生产环境不等于开发环境。原生vLLM接口虽然标准、高效但它默认没有身份验证、没有调用频控、没有请求日志审计、没有统一错误码、也没有业务层的参数校验和上下文增强。比如你的前端应用直接暴露vLLM地址等于把模型服务完全裸奔在公网多个团队共用一个GPU节点没人知道谁在高频刷请求某个用户发来超长提示词或恶意payloadvLLM会照单全收可能拖慢整机响应你想给不同客户返回带水印的回复或者自动追加免责声明——这些逻辑没法塞进vLLM配置里。FastAPI不是为了“替代”vLLM而是做它前面那道可控、可管、可审计的业务网关。就像给一辆高性能跑车加装了方向盘、油门踏板、仪表盘和行车记录仪——引擎还是vLLM但驾驶权、监控权和责任归属回到了你手里。本教程不讲理论只带你一步步落地从零启动一个带完整鉴权的FastAPI服务对接本地vLLM支持Bearer Token认证、请求限流、结构化日志并提供可直接运行的代码。2. 环境准备与依赖安装我们假设你已在CSDN星图平台成功拉起GLM-4.7-Flash镜像含vLLM推理服务和Web UI且能通过curl http://127.0.0.1:8000/health确认vLLM正常运行。接下来在同一台机器上新建一个独立Python环境避免与系统或vLLM环境冲突# 创建虚拟环境推荐使用conda或venv python -m venv ./glm47flash-api-env source ./glm47flash-api-env/bin/activate # Linux/Mac # .\glm47flash-api-env\Scripts\activate # Windows # 安装核心依赖 pip install --upgrade pip pip install fastapi uvicorn python-jose[cryptography] passlib python-multipart requests loguru说明fastapiuvicorn是Web框架和ASGI服务器python-jose用于JWT生成与校验passlib辅助密码哈希虽本例不用密码登录但为扩展留接口loguru替代原生logging更简洁易用requests用于向本地vLLM发起HTTP调用。无需安装PyTorch、transformers或vLLM——这些已由镜像预装我们只做API代理层。3. 鉴权体系设计与Token管理我们采用行业通用的Bearer Token JWTJSON Web Token方案轻量、无状态、易集成。整个流程如下运维人员预先生成一组长期有效的API密钥如sk-glm47flash-prod-xxxxx将密钥存入内存字典或简单文件生产环境建议用Redis或数据库用户携带Authorization: Bearer sk-glm47flash-prod-xxxxx请求APIFastAPI中间件解析Token校验是否存在且未过期校验通过则放行否则返回401 Unauthorized。这里不引入OAuth2复杂流程也不做用户注册登录——因为这是模型服务网关不是用户管理系统。重点是快、稳、可追溯。创建auth.py文件定义鉴权逻辑# auth.py from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from jose import JWTError, jwt from loguru import logger import os # 模拟API密钥池生产环境请替换为数据库/Redis API_KEYS { sk-glm47flash-prod-2024: production-team, sk-glm47flash-dev-123: development-team, } security HTTPBearer() def verify_api_key(credentials: HTTPAuthorizationCredentials Depends(security)) - str: 验证Bearer Token是否在白名单中 返回关联的团队标识可用于后续日志或限流 token credentials.credentials if token not in API_KEYS: logger.warning(fInvalid API key attempted: {token[:8]}...) raise HTTPException( status_codestatus.HTTP_401_UNAUTHORIZED, detailInvalid or expired API key, headers{WWW-Authenticate: Bearer}, ) logger.info(fValid API key used by: {API_KEYS[token]}) return API_KEYS[token]这段代码做了三件事拦截所有带Authorization: Bearer xxx的请求检查Token是否在预设字典中记录日志并返回所属团队名为后续按团队限流埋点。4. FastAPI主服务搭建与vLLM代理创建main.py这是整个服务的核心# main.py from fastapi import FastAPI, Depends, HTTPException, status, Request from fastapi.responses import StreamingResponse, JSONResponse from fastapi.middleware.cors import CORSMiddleware from loguru import logger import requests import json import time from typing import Dict, Any, Optional from auth import verify_api_key app FastAPI( titleGLM-4.7-Flash API Gateway, descriptionFastAPI wrapper for GLM-4.7-Flash vLLM service with auth logging, version1.0.0 ) # 允许前端跨域如你的React/Vue项目 app.add_middleware( CORSMiddleware, allow_origins[*], allow_credentialsTrue, allow_methods[*], allow_headers[*], ) # vLLM服务地址镜像内固定为8000端口 VLLM_BASE_URL http://127.0.0.1:8000 app.middleware(http) async def log_requests(request: Request, call_next): 全局请求日志中间件 start_time time.time() try: response await call_next(request) process_time time.time() - start_time logger.info( f{request.method} {request.url.path} f{response.status_code} {process_time:.3f}s ffrom {request.client.host} ) return response except Exception as e: process_time time.time() - start_time logger.error( f{request.method} {request.url.path} ERROR {process_time:.3f}s ffrom {request.client.host} - {str(e)} ) raise app.post(/v1/chat/completions) async def chat_completions( request: Request, team_id: str Depends(verify_api_key) # 注入鉴权结果 ): 代理vLLM的chat/completions接口增加鉴权与日志 try: # 读取原始JSON体 body await request.json() # 强制指定model路径避免客户端乱填 body[model] /root/.cache/huggingface/ZhipuAI/GLM-4.7-Flash # 添加团队标识到日志上下文可选 logger.contextualize(teamteam_id) # 转发请求到vLLM vllm_response requests.post( f{VLLM_BASE_URL}/v1/chat/completions, jsonbody, timeout120 # 给大模型充足响应时间 ) # 流式响应处理 if body.get(stream, False): return StreamingResponse( vllm_response.iter_content(chunk_size64), media_typetext/event-stream, status_codevllm_response.status_code ) # 普通JSON响应 return JSONResponse( contentvllm_response.json(), status_codevllm_response.status_code ) except requests.exceptions.Timeout: logger.error(vLLM timeout after 120s) raise HTTPException(status_code504, detailModel inference timeout) except requests.exceptions.ConnectionError: logger.error(Cannot connect to vLLM service) raise HTTPException(status_code503, detailvLLM service unavailable) except Exception as e: logger.exception(Unexpected error in chat_completions) raise HTTPException(status_code500, detailInternal server error) app.get(/health) def health_check(): 健康检查端点供K8s或监控系统调用 return {status: ok, timestamp: int(time.time())} if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8001, workers2)关键点解析app.middleware(http)全局记录每个请求耗时、状态码、来源IP便于排查问题team_id Depends(verify_api_key)将鉴权结果注入路由后续可用来做团队级限流或计费body[model] ...强制覆盖客户端传入的model字段防止误调其他模型StreamingResponse原样透传vLLM的SSE流式响应前端体验无缝timeout120大模型推理可能较长设合理超时避免挂起/health标准健康检查方便容器编排系统探活。5. 启动服务与测试验证5.1 启动FastAPI网关在镜像终端中执行# 确保已激活虚拟环境 source ./glm47flash-api-env/bin/activate # 启动服务监听8001端口避开vLLM的8000 uvicorn main:app --host 0.0.0.0 --port 8001 --workers 2 --reload--workers 2双进程提升并发能力--reload开发时自动重载生产环境请去掉日志会实时输出到终端同时被loguru写入文件默认runtime.log。5.2 测试鉴权是否生效打开新终端用curl测试# ❌ 无Token → 应返回401 curl -X POST http://127.0.0.1:8001/v1/chat/completions \ -H Content-Type: application/json \ -d {messages:[{role:user,content:你好}]} # ❌ 错误Token → 应返回401 curl -X POST http://127.0.0.1:8001/v1/chat/completions \ -H Authorization: Bearer invalid-key \ -H Content-Type: application/json \ -d {messages:[{role:user,content:你好}]} # 正确Token → 应返回200并生成回复 curl -X POST http://127.0.0.1:8001/v1/chat/completions \ -H Authorization: Bearer sk-glm47flash-prod-2024 \ -H Content-Type: application/json \ -d { messages: [{role:user,content:用中文写一首关于春天的五言绝句}], temperature: 0.5, max_tokens: 256 }观察FastAPI终端日志你会看到类似2024-06-15 14:22:31.892 | INFO | __main__:log_requests:42 - POST /v1/chat/completions 200 1.245s from 127.0.0.1 2024-06-15 14:22:31.893 | INFO | auth:verify_api_key:28 - Valid API key used by: production-team说明鉴权、日志、代理全部走通。5.3 测试流式响应前端友好用Python脚本模拟流式消费# test_stream.py import requests url http://127.0.0.1:8001/v1/chat/completions headers { Authorization: Bearer sk-glm47flash-prod-2024, Content-Type: application/json } data { model: /root/.cache/huggingface/ZhipuAI/GLM-4.7-Flash, messages: [{role: user, content: 请逐字解释‘人工智能’四个字的含义}], stream: True } with requests.post(url, headersheaders, jsondata, streamTrue) as r: for line in r.iter_lines(): if line: line_str line.decode(utf-8) if line_str.startswith(data: ): try: chunk json.loads(line_str[6:]) if choices in chunk and chunk[choices][0][delta].get(content): print(chunk[choices][0][delta][content], end, flushTrue) except: pass运行后文字会像打字机一样逐字输出证明流式链路完整。6. 生产就绪增强限流与错误统一处理当前版本已满足基础需求但离生产还差两步防刷限流和错误标准化。我们用几行代码补上。6.1 基于团队ID的简单限流修改main.py在顶部添加限流逻辑使用内存计数器生产环境建议换Redis# main.py 开头新增 from collections import defaultdict, deque import time # 内存限流每分钟最多30次请求 per team RATE_LIMIT_WINDOW 60 # 秒 RATE_LIMIT_MAX 30 _request_counts defaultdict(deque) # team_id - [timestamp, timestamp, ...] def check_rate_limit(team_id: str) - bool: now time.time() # 清理窗口外的旧请求记录 while _request_counts[team_id] and _request_counts[team_id][0] now - RATE_LIMIT_WINDOW: _request_counts[team_id].popleft() # 检查是否超限 if len(_request_counts[team_id]) RATE_LIMIT_MAX: return False _request_counts[team_id].append(now) return True然后在chat_completions函数开头加入# 在 try: 之后、读取body之前插入 if not check_rate_limit(team_id): logger.warning(fRate limit exceeded for team: {team_id}) raise HTTPException( status_codestatus.HTTP_429_TOO_MANY_REQUESTS, detailToo many requests, please try again later )6.2 统一错误响应格式FastAPI默认错误返回HTML或纯文本不利于前端解析。我们定义一个标准错误响应类# 在main.py中添加 from pydantic import BaseModel class ErrorResponse(BaseModel): error: dict app.exception_handler(HTTPException) async def http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( status_codeexc.status_code, content{ error: { message: exc.detail, type: api_error, param: None, code: str(exc.status_code) } } ) app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): logger.exception(Unhandled exception) return JSONResponse( status_code500, content{ error: { message: An unexpected error occurred, type: server_error, param: None, code: 500 } } )现在所有错误都返回结构化JSON前端可统一处理{ error: { message: Invalid or expired API key, type: api_error, param: null, code: 401 } }7. 总结你已掌握模型服务网关的核心能力回顾整个过程你亲手构建了一个具备生产级特性的GLM-4.7-Flash API网关安全可控通过Bearer Token实现最小权限访问杜绝未授权调用可观测全链路结构化日志精确到毫秒级耗时与来源IP高可用健康检查超时熔断异常兜底保障服务稳定性易扩展模块化设计后续可轻松接入Redis限流、Prometheus监控、OpenTelemetry追踪零侵入完全不改动vLLM源码仅做轻量代理升级vLLM不影响网关。这不仅是“封装一个API”更是为你搭建了一条通往AI工程化的标准路径——模型是引擎API是方向盘而网关就是你手里的驾驶执照。下一步你可以➡ 将API密钥存储到环境变量或Secret Manager➡ 集成Prometheus exporter暴露QPS、延迟、错误率指标➡ 为不同团队配置差异化max_tokens和temperature默认值➡ 添加异步队列如Celery处理超长请求避免阻塞主线程。技术没有银弹但扎实的工程实践永远是最可靠的护城河。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询