You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在FastAPI中通过Pydantic强制UTC ISO格式时间戳输入

解决方案

要严格限制请求体中的timestamp必须为UTC ISO 8601格式(如2015-09-01T16:09:00.000Z),你可以通过Pydantic的字段验证器实现精确校验。以下是修改后的完整代码:

from typing import Optional
from fastapi import FastAPI, Response
from pydantic import BaseModel, field_validator
from datetime import datetime, timezone
import re

app = FastAPI()

# 注意:原示例中的timestamp格式存在笔误,毫秒部分应该用小数点而非冒号
measurements = [
    {
      "timestamp": "2015-09-01T16:09:00.000Z",
      "temperature": 27.1
    },
    {
        "timestamp": "2016-09-01T16:09:00.000Z",
        "temperature": 21.3
    }
]

class MeasurementIn(BaseModel):
    timestamp: datetime
    temperature: Optional[float]    

    @field_validator("timestamp")
    def enforce_utc_iso_format(cls, value):
        # 验证时间必须是UTC时区
        if value.tzinfo is None or value.tzinfo != timezone.utc:
            raise ValueError("timestamp必须是UTC时区,格式需带'Z'后缀")
        
        # 将datetime转换为标准UTC ISO字符串,用于格式校验
        utc_iso_str = value.isoformat().replace("+00:00", "Z")
        # 正则匹配严格格式:YYYY-MM-DDTHH:MM:SS.sssZ
        format_pattern = r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"
        if not re.match(format_pattern, utc_iso_str):
            raise ValueError("timestamp格式必须为'YYYY-MM-DDTHH:MM:SS.sssZ'")
        
        return value

@app.post("/measurements")
async def create_measurement(m: MeasurementIn, response: Response):
    # 将datetime转换为标准UTC ISO字符串存入列表
    measurements.append({
        "timestamp": m.timestamp.isoformat().replace("+00:00", "Z"),
        "temperature": m.temperature
    })
    response.status_code = 201
    return {"message": "Measurement created", "data": m.dict()}

关键说明

  1. 时区校验:验证器会检查解析后的datetime对象是否带有UTC时区信息,确保客户端发送的时间戳必须带Z后缀(表示UTC)。
  2. 格式严格匹配:通过正则表达式强制要求时间戳包含毫秒部分(.sss),且整体符合YYYY-MM-DDTHH:MM:SS.sssZ格式。
  3. 错误反馈:如果客户端发送不符合要求的时间戳,FastAPI会自动返回422验证错误,包含具体的错误信息。

注意事项

  • 如果你使用的是Pydantic v1版本,需要将@field_validator替换为@validator,并导入from pydantic import validator。
  • 原示例中的时间戳格式(2015-09-01T16:09:00:000Z)是错误的,标准ISO 8601格式中毫秒部分应该用小数点分隔,而非冒号。

内容的提问来源于stack exchange,提问作者meallhour

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:10:33