共计 3905 个字符,预计需要花费 10 分钟才能阅读完成。
目录
环境准备
- Python 环境要求
- 确认 Python 版本≥3.8(推荐 3.10+)
-
检查现有版本:
python --version
-
依赖安装
- 核心 SDK 安装:
pip install deepseek-sdk python-dotenv httpx - 开发工具推荐:
pip install black pylint pytest
认证流程
- API 密钥获取
- 登录 DeepSeek 控制台创建应用
-
在 ” 凭证管理 ” 页面生成 API Key
-
安全存储方案
- 创建
.env文件(需加入.gitignore):# .env 示例 DEEPSEEK_API_KEY=sk-your-key-here - 加载配置的 Python 代码:
from dotenv import load_dotenv import os load_dotenv() API_KEY = os.getenv('DEEPSEEK_API_KEY')
核心代码实现
完整封装类实现(保存为deepseek_client.py):
import httpx
import json
from typing import Optional, Dict, Any
import time
import logging
logger = logging.getLogger(__name__)
class DeepSeekClient:
"""DeepSeek API 客户端封装"""
def __init__(self, api_key: str, base_url: str = "https://api.deepseek.com/v1"):
self.api_key = api_key
self.base_url = base_url
self.timeout = httpx.Timeout(30.0, read=60.0)
async def _make_request(
self,
method: str,
endpoint: str,
payload: Optional[Dict] = None,
max_retries: int = 3
) -> Dict[str, Any]:
"""带重试机制的请求核心方法"""
url = f"{self.base_url}/{endpoint}"
headers = {"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
async with httpx.AsyncClient(timeout=self.timeout) as client:
for attempt in range(max_retries):
try:
response = await client.request(
method,
url,
json=payload,
headers=headers
)
# 处理 429 状态码(限流)if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", "5"))
logger.warning(f"Rate limited, retrying after {retry_after}s...")
time.sleep(retry_after)
continue
response.raise_for_status()
return response.json()
except httpx.HTTPStatusError as e:
if attempt == max_retries - 1:
logger.error(f"API request failed: {str(e)}")
raise
logger.warning(f"Attempt {attempt + 1} failed, retrying...")
time.sleep(2 ** attempt) # 指数退避
raise RuntimeError("Max retries exceeded")
async def generate_text(self, prompt: str, **kwargs) -> Dict[str, Any]:
"""文本生成接口"""
payload = {
"prompt": prompt,
"max_tokens": kwargs.get("max_tokens", 512),
"temperature": kwargs.get("temperature", 0.7)
}
return await self._make_request("POST", "completions", payload)
# 使用示例
async def main():
from dotenv import load_dotenv
import os
load_dotenv()
client = DeepSeekClient(os.getenv("DEEPSEEK_API_KEY"))
try:
result = await client.generate_text("Python 的 GIL 是什么?")
print(json.dumps(result, indent=2))
except Exception as e:
print(f"Error: {str(e)}")
if __name__ == "__main__":
import asyncio
asyncio.run(main())
性能优化
- 同步 vs 异步性能对比
- 测试代码:
import time async def test_concurrent_requests(): start = time.time() tasks = [client.generate_text(f"Test {i}") for i in range(10)] await asyncio.gather(*tasks) print(f"Async time: {time.time() - start:.2f}s") def test_sync_requests(): start = time.time() for i in range(10): asyncio.run(client.generate_text(f"Test {i}")) print(f"Sync time: {time.time() - start:.2f}s") -
典型结果(本地测试):
- 同步请求:~12.5 秒
- 异步请求:~1.8 秒
-
异步优化建议
- 使用连接池:
async with httpx.AsyncClient(limits=httpx.Limits(max_connections=100), timeout=httpx.Timeout(30.0) ) as client: - 批量请求处理:
async def batch_process(prompts: List[str]): semaphore = asyncio.Semaphore(20) # 并发控制 async def limited_task(prompt): async with semaphore: return await client.generate_text(prompt) return await asyncio.gather(*[limited_task(p) for p in prompts])
生产环境建议
- QPS 限制策略
-
令牌桶算法实现:
from collections import deque import time class RateLimiter: def __init__(self, max_calls: int, period: float): self.calls = deque() self.period = period self.max_calls = max_calls async def wait(self): now = time.time() while len(self.calls) >= self.max_calls: if now - self.calls[0] > self.period: self.calls.popleft() else: await asyncio.sleep(self.calls[0] + self.period - now) now = time.time() self.calls.append(now) -
日志记录规范
- 结构化日志配置:
import structlog structlog.configure( processors=[structlog.processors.JSONRenderer() ], logger_factory=structlog.PrintLoggerFactory()) -
关键信息记录:
logger.info("API request", endpoint=endpoint, status_code=response.status_code, latency=response.elapsed.total_seconds()) -
敏感信息加密
- 使用 Fernet 加密:
from cryptography.fernet import Fernet key = Fernet.generate_key() # 保存到安全位置 cipher = Fernet(key) encrypted = cipher.encrypt(b"secret_api_key") decrypted = cipher.decrypt(encrypted)
延伸思考
- 如何实现 API 调用结果的本地缓存?
- 考虑使用 Redis 或 Memcached 作为缓存层
-
设计合理的缓存键(如 prompt 的 hash 值)和过期策略
-
当需要处理大模型流式响应时应该如何改造现有代码?
- 修改请求方法支持 stream=True
-
使用异步生成器逐步处理响应块
-
在多租户场景下如何设计权限隔离方案?
- 为每个租户创建独立 API 密钥
- 在代理层实现请求路由和配额管理
正文完

