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

如何通过Pydantic自动解码AWS Lambda中S3事件的URL编码Key?

问题

在AWS Lambda函数中使用Pydantic验证并类型化传入的S3 Event,事件结构如下:

{
  "Records": [
    {
      "s3": {
        "bucket": {
          "name": "my-bucket"
        },
        "object": {
          "key": "MYKEY%28CSV%29/XXXX.CSV"
        }
      }
    }
  ]
}

对应的Pydantic模型定义如下:

from pydantic import BaseModel

class ObjectInfo(BaseModel):
    key: str

class BucketInfo(BaseModel):
    name: str

class S3Schema(BaseModel):
    bucket: BucketInfo
    object: ObjectInfo

class Record(BaseModel):
    s3: S3Schema

class DeletionEvent(BaseModel):
    Records: list[Record]

def handler(event: dict, _):
    eventTyped = DeletionEvent(**event)
    return True

需要将key字段的URL编码值(如MYKEY%28CSV%29/XXXX.CSV)自动解码为原始值MYKEY(CSV)/XXXX.CSV,希望通过Pydantic自动完成解码,而非手动使用urllib.parse.unquote_plus处理。

解决方案

方法一:字段验证器直接处理

在ObjectInfo模型的key字段上添加Pydantic字段验证器,自动完成URL解码:

from pydantic import BaseModel, field_validator
from urllib.parse import unquote_plus

class ObjectInfo(BaseModel):
    key: str

    @field_validator('key')
    def decode_s3_key(cls, value):
        return unquote_plus(value)

class BucketInfo(BaseModel):
    name: str

class S3Schema(BaseModel):
    bucket: BucketInfo
    object: ObjectInfo

class Record(BaseModel):
    s3: S3Schema

class DeletionEvent(BaseModel):
    Records: list[Record]

def handler(event: dict, _):
    event_typed = DeletionEvent(**event)
    # 此时event_typed.Records[0].s3.object.key已解码为MYKEY(CSV)/XXXX.CSV
    return True

这种方式针对性强,仅对目标字段做解码,逻辑直观,无需额外类型定义。

方法二:自定义可复用的URL解码类型

如果多个字段或模型需要URL解码逻辑,可以自定义一个字符串类型,后续直接复用:

from pydantic import BaseModel, GetCoreSchemaHandler
from pydantic_core import core_schema
from urllib.parse import unquote_plus
from typing import Any

class UrlDecodedStr(str):
    @classmethod
    def __get_pydantic_core_schema__(cls, source_type: Any, handler: GetCoreSchemaHandler) -> core_schema.CoreSchema:
        # 基于基础字符串类型扩展,添加解码验证逻辑
        return core_schema.no_info_wrap_validator_function(
            cls.decode_value,
            handler(str),
        )

    @classmethod
    def decode_value(cls, value: str) -> str:
        return unquote_plus(value)

class ObjectInfo(BaseModel):
    key: UrlDecodedStr  # 直接使用自定义类型

# 其余BucketInfo、S3Schema等模型保持原定义不变

后续任何需要URL解码的字符串字段,只需将类型指定为UrlDecodedStr即可自动完成解码,适合多场景复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:59:58