Django Ninja第三方API集成:调用外部服务

Django Ninja第三方API集成:调用外部服务

【免费下载链接】django-ninja 💨 Fast, Async-ready, Openapi, type hints based framework for building APIs 【免费下载链接】django-ninja 项目地址: https://gitcode.com/gh_mirrors/dj/django-ninja

在现代Web开发中,与第三方服务交互是常见需求。Django Ninja作为基于类型提示的高性能API框架,提供了简洁的方式来实现外部服务集成。本文将从同步和异步两种方式,详细介绍如何在Django Ninja项目中调用第三方API,解决超时处理、错误捕获等关键问题。

同步调用第三方API

同步调用适用于简单场景,可直接使用Python标准库或第三方HTTP客户端。以下是使用requests库调用外部服务的示例:

# someapp/api.py
import requests
from ninja import Router
from pydantic import BaseModel

router = Router()

class WeatherResponse(BaseModel):
    city: str
    temperature: float
    description: str

@router.get("/weather", response=WeatherResponse)
def get_weather(request, city: str):
    """获取指定城市天气信息"""
    api_key = "your_api_key"
    url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric"
    
    try:
        response = requests.get(url, timeout=5)
        response.raise_for_status()  # 抛出HTTP错误
        data = response.json()
        
        return {
            "city": data["name"],
            "temperature": data["main"]["temp"],
            "description": data["weather"][0]["description"]
        }
    except requests.exceptions.RequestException as e:
        return {"error": str(e)}, 503

代码中使用requests.get()发起同步请求,并通过try-except捕获网络异常。响应模型WeatherResponse确保API输出符合类型规范,这是Django Ninja的核心特性之一。

异步调用第三方API

对于高并发场景,异步调用能显著提升性能。Django Ninja原生支持异步视图,配合aiohttp库可实现非阻塞HTTP请求:

# someapp/api.py
import aiohttp
from ninja import Router
from pydantic import BaseModel

router = Router()

class GitHubUser(BaseModel):
    login: str
    name: str
    public_repos: int

@router.get("/github/user", response=GitHubUser)
async def get_github_user(request, username: str):
    """获取GitHub用户信息"""
    url = f"https://api.github.com/users/{username}"
    
    async with aiohttp.ClientSession() as session:
        try:
            async with session.get(url, timeout=10) as response:
                response.raise_for_status()
                data = await response.json()
                return {
                    "login": data["login"],
                    "name": data.get("name", "N/A"),
                    "public_repos": data["public_repos"]
                }
        except aiohttp.ClientError as e:
            return {"error": str(e)}, 503

异步视图通过async def定义,使用aiohttp.ClientSession发起非阻塞请求。这种方式特别适合需要同时调用多个API的场景,避免因等待单个请求而阻塞整个应用。

高级集成模式

1. API调用封装

将第三方API调用封装为独立服务类,可提高代码复用性和可测试性:

# someapp/services.py
import httpx
from typing import Dict, Optional

class APIClient:
    def __init__(self, base_url: str, timeout: int = 10):
        self.base_url = base_url
        self.timeout = timeout
        
    def get(self, endpoint: str, params: Optional[Dict] = None) -> Dict:
        """同步GET请求"""
        with httpx.Client(timeout=self.timeout) as client:
            response = client.get(f"{self.base_url}/{endpoint}", params=params)
            response.raise_for_status()
            return response.json()
            
    async def async_get(self, endpoint: str, params: Optional[Dict] = None) -> Dict:
        """异步GET请求"""
        async with httpx.AsyncClient(timeout=self.timeout) as client:
            response = await client.get(f"{self.base_url}/{endpoint}", params=params)
            response.raise_for_status()
            return await response.json()

在视图中使用封装的客户端:

# someapp/api.py
from ninja import Router
from .services import APIClient

router = Router()
client = APIClient("https://api.github.com")

@router.get("/github/repos")
async def list_repos(request, username: str):
    """列出用户GitHub仓库"""
    data = await client.async_get(f"users/{username}/repos")
    return [{"name": repo["name"], "stars": repo["stargazers_count"]} for repo in data]

2. 集成Swagger文档

Django Ninja自动生成OpenAPI文档,可直观展示第三方API集成效果。访问/docs路径即可看到交互式API文档界面:

Swagger UI文档

通过在视图函数中添加文档字符串,可自动生成API说明:

@router.get("/weather", response=WeatherResponse)
def get_weather(request, city: str):
    """
    获取城市天气信息
    
    - **city**: 城市名称(如"Beijing")
    - 返回当前温度和天气状况
    """
    # 实现代码...

文档生成功能由ninja/openapi/views.py提供支持,自动解析类型提示和函数注释,生成符合OpenAPI规范的接口文档。

错误处理与最佳实践

超时控制

第三方API调用必须设置超时,避免长时间阻塞:

# 同步超时设置
response = requests.get(url, timeout=5)  # 5秒超时

# 异步超时设置
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)):
    pass

重试机制

使用tenacity库实现失败重试:

from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10))
async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            response.raise_for_status()
            return await response.json()

安全存储API密钥

敏感信息应使用Django设置存储,避免硬编码:

# settings.py
THIRD_PARTY_APIS = {
    "WEATHER_API_KEY": os.environ.get("WEATHER_API_KEY"),
    "GITHUB_TOKEN": os.environ.get("GITHUB_TOKEN")
}

# 在视图中使用
from django.conf import settings

api_key = settings.THIRD_PARTY_APIS["WEATHER_API_KEY"]

项目结构与代码组织

推荐的第三方API集成项目结构:

someapp/
├── api.py          # API视图定义
├── services.py     # 第三方服务客户端
├── schemas.py      # 请求/响应模型
├── exceptions.py   # 自定义异常
└── tests.py        # 测试用例

这种结构将数据模型、业务逻辑和API接口分离,符合Django应用的最佳实践。相关代码可参考测试项目中的demo_project/someapp/api.py实现。

总结

Django Ninja提供了灵活的方式集成第三方API,无论是简单的同步调用还是高性能的异步请求,都能通过简洁的代码实现。核心要点包括:

  1. 使用类型提示和Pydantic模型确保数据安全
  2. 优先采用异步调用提升并发性能
  3. 封装API客户端提高代码复用性
  4. 完善错误处理和超时控制
  5. 利用自动生成的OpenAPI文档简化测试

通过本文介绍的方法,开发者可以高效地将外部服务集成到Django Ninja项目中,构建功能完善的API应用。更多高级用法可参考官方文档docs/guides/async-support.mddocs/reference/api.md

【免费下载链接】django-ninja 💨 Fast, Async-ready, Openapi, type hints based framework for building APIs 【免费下载链接】django-ninja 项目地址: https://gitcode.com/gh_mirrors/dj/django-ninja

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值