Hug API框架中的类型注解详解
什么是Hug中的类型注解
Hug框架充分利用了Python 3的类型注解特性,为API开发提供了强大的验证和规范功能。在Hug中,类型注解不仅仅是文档工具,更是请求参数验证的核心机制。
类型注解的四种使用方式
在Hug框架中,类型注解可以设置为以下四种形式:
- 转换函数:可以是内置函数或自定义函数,如str、int等,它们接收值并尝试转换,如果格式不正确则抛出异常
- Hug内置类型:如hug.types.text、hug.types.number等,这些是专门设计的转换函数,提供更丰富的上下文信息和良好的默认错误消息
- Marshmallow类型/模式:从Hug 2.0.0开始,Marshmallow成为一等公民,其定义的所有字段和模式都可以用作类型注解
- 纯字符串:当使用普通Python字符串作为类型注解时,Hug仅将其用于生成文档,而不会在验证阶段应用
基本示例
import hug
@hug.get()
def hello(first_name: hug.types.text, last_name: 'Family Name', age: int):
print(f"Hi {first_name} {last_name}!")
这个简单的端点展示了三种不同的类型注解用法:Hug类型、字符串文档和Python内置类型。
验证机制工作原理
当类型注解在转换过程中抛出异常时,Hug会将其视为验证失败。默认情况下,所有错误都会被收集到错误字典中,并在路由函数被调用前返回。开发者可以通过以下方式自定义错误处理:
- 使用
on_invalid
路由选项转换错误 - 通过
output_invalid
指定错误输出的特定格式 - 设置
raise_on_invalid=True
让Hug完全不处理验证错误,直接抛出异常
Hug内置类型详解
Hug提供了一系列内置类型来处理常见的API场景:
数值类型
number
:验证整数float_number
:验证浮点数decimal
:转换为Python Decimal对象in_range(lower, upper)
:验证数值在指定范围内less_than(limit)
:验证数值小于限制greater_than(minimum)
:验证数值大于最小值
文本类型
text
:验证单字符串参数length(lower, upper)
:验证文本长度在范围内shorter_than(limit)
:验证文本短于限制longer_than(limit)
:验证文本长于限制cut_off(limit)
:在指定索引处截断文本
其他实用类型
uuid
:验证UUID格式multiple
:确保参数作为列表传递boolean
:基本HTTP风格布尔值smart_boolean
:更智能的布尔值检测delimited_list(delimiter)
:按分隔符分割为列表one_of(values)
:验证值在指定集合中mapping(dict)
:类似one_of,但带值转换multi(types)
:允许多种可接受类型
扩展和创建自定义类型
继承方式
import hug
class TheAnswer(hug.types.Text):
"""自定义文档说明"""
def __call__(self, value):
value = super().__call__(value)
if value != 'fourty-two':
raise ValueError('这不是万物之答案')
return value
通过继承基础类型并重写__call__
方法,可以自定义转换逻辑;重写__init__
则可以修改类型参数。
装饰器方式
import hug
@hug.type(extend=hug.types.number)
def the_answer(value):
"""自定义文档说明"""
if value != 42:
raise ValueError('这不是万物之答案')
return value
装饰器方式更简洁,适合在基础类型上添加额外转换或修改文档。
Marshmallow集成
Marshmallow是一个高级的序列化、反序列化和验证库。Hug支持使用Marshmallow字段和模式作为输入类型。
日期计算示例
import datetime as dt
import hug
from marshmallow import fields
from marshmallow.validate import Range
@hug.get('/dateadd', examples="value=1973-04-10&addend=63")
def dateadd(value: fields.Date(),
addend: fields.Int(validate=Range(min=1))):
"""日期加法计算"""
delta = dt.timedelta(days=addend)
result = value + delta
return {'result': result}
这个示例展示了如何使用Marshmallow的Date字段和带验证的Int字段,以及如何通过validate参数添加额外验证规则。
最佳实践
- 优先使用Hug内置类型:它们专为API设计,提供了良好的默认错误消息
- 复杂验证使用Marshmallow:当需要复杂验证规则时,Marshmallow提供了更丰富的功能
- 保持文档一致性:即使使用纯字符串注解,也要确保它们准确描述参数
- 自定义类型要明确:创建自定义类型时,确保错误消息清晰,便于API使用者理解
通过合理利用Hug的类型注解系统,开发者可以构建出既安全又易于使用的API接口,同时自动获得详细的API文档。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考