之前一直用Flask,为了方便算法工程师和分析师使用,还自己简单封装了一下:https://github.com/ibbd-dev/python-fire-rest
主要是为了使用起来更加简单些。
前些日子看见有人介绍FastAPI,了解了一下,就是自己喜欢的模样,趁着团队在做框架选型,顺便把在新项目的接口上尝试了一下。
FastAPI官方文档:https://fastapi.tiangolo.com/
安装及简单入门就不介绍了,自己看文档。
接口文件
接口文件main.py:
from fastapi import FastAPI
from image_utils.convert import base64_pil, pil_base64
from settings import RMWatermarkParams, SealExtractParams
from settings import RMWatermarkResp, SealExtractResp
from remove_watermark_pdf_scan_simple import remove_watermark
from seal import seal_extract, seal_compare, seal_remove
# 设置接口页面基础信息
description = """
主要包含水印,印章,签名等目标的去除和比对等算法。
说明:
- 如无特殊说明,接口输入输出均使用json
- 输入输出的图像,均使用base64格式
印章类型:
- circle:圆形(包含圆形和椭圆)
- rectangle: 矩形
"""
app = FastAPI(
title="CV算法接口",
description=description,
version="1.0",
)
@app.get("/")
async def root():
return {"文档地址": "http://host:port/docs"}
@app.post('/remove_watermark', response_model=RMWatermarkResp,
summary="水印去除")
async def api_rm_watermark(
params: RMWatermarkParams
):
""" 简单粗暴去水印"""
params = dict(params)
params['img'] = base64_pil(params['img'])
img = remove_watermark(**params)
return {
"image": pil_base64(img)
}
@app.post('/extract_seal', response_model=SealExtractResp,
summary="提取印章")
async def api_extract_seal(
params: SealExtractParams
):
"""从图片中提取出印章图像,只需要截图传包含印章的部分截图即可。"""
return seal_extract(**dict(params))
我们的场景只是用来封装算法接口,FastAPI还是很适用的,接口输入输出都使用JSON格式,接口文档不用单独写了,都定义在配置文件里。
算法工程师只需要实现具体的功能,如seal_extract实现的是印章提取,可以独立实现,外部使用FastAPI进行包装,相互解耦:
FastAPI在启动的时候可以指定一些基础信息,如页面标题,描述,版本等,而每个接口还可以指定summary。
配置文件
配置文件settings.py:
from typing import List
from pydantic import BaseModel, Field
class RMWatermarkParams(BaseModel):
img: str = Field(..., title="输入图片,base64格式字符串")
thr: int = Field(200, title="去除图片中像素阈值",
example=200, gt=0, le=255)
distance: int = Field(1, title="去除图片中像素距离",
example=1, gt=0)
class RMWatermarkResp(BaseModel):
image: str = Field(..., title="去水印后的图像,jpg,base64格式")
class SealExtractParams(BaseModel):
image: str = Field(..., title="待检测图像,base64格式字符串")
seal_type: str = Field("circle", title="印章的类型", example='circle')
class SealExtractResp(BaseModel):
image: str = Field(..., title="印章提取的图像(相当于抠图),jpg,base64格式")
box: List[int] = Field(..., title="印章的位置",
description="左上角和右下角坐标[x1, y1, x2, y2]",
example=[1, 1, 100, 100])
如印章提取函数seal_extract,输入输出参数:
为了定义比较规范,输入参数类名以Params结尾,而输出参数类名以Resp结尾。
在输入输出字段中,除了可以定义类型,还可以定义变量的取值范围,如le,gt等,如果是字符串还可以定义字符串长度的范围,如果输入输出不满足条件,则参数校验无法通过。
而list类型还可以定义成这样List[int],元素类型为int,组合类型还有更多的用法,具体可以看文档。
接口界面效果
启动脚本:
sudo docker run -ti -d \
--name ibbd-cv \
--restart always \
-v "$PWD/src":/cv \
-p 20925:8000 \
-w /cv \
registry.cn-hangzhou.aliyuncs.com/ibbd/python3:cv \
uvicorn main:app --host 0.0.0.0 --reload
参数--reload通常只用于开发或者测试环境。启动之后,界面如:
点击提取印章接口:
如果正常返回,则http状态码code=200。而如果异常,则如下:
对于开发工程师已经足够了,不过如果对于算法工程师,却还是有点啰嗦,有时间还是应该再简化一些,那样易用性会更好些。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有