From 1a092248eb9a8c8128a4a4965b76a624a233d9e3 Mon Sep 17 00:00:00 2001 From: mamamiyear Date: Wed, 12 Nov 2025 00:51:11 +0800 Subject: [PATCH] feat: add api routers for recognition - post /recognition/input - post /recognition/image --- pyproject.toml | 1 + src/main.py | 5 ++++- src/web/api.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++- uv.lock | 11 +++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dddcca6..923f3d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ dependencies = [ "fastapi>=0.118.3", "langchain==0.3.27", "langchain-openai==0.3.35", + "python-multipart>=0.0.20", "qiniu>=7.17.0", "sqlalchemy>=2.0.44", "uvicorn>=0.38.0", diff --git a/src/main.py b/src/main.py index d4fbd30..c0b1460 100644 --- a/src/main.py +++ b/src/main.py @@ -4,7 +4,7 @@ import os import argparse import uvicorn from services import people as people_service -from utils import config, logger, rldb +from utils import config, logger, obs, ocr, rldb from web.api import api @@ -20,6 +20,9 @@ def main(): rldb.init() + ocr.init() + obs.init() + people_service.init() conf = config.get_instance() diff --git a/src/web/api.py b/src/web/api.py index f41061d..88ebe6c 100644 --- a/src/web/api.py +++ b/src/web/api.py @@ -1,10 +1,14 @@ +import os +import uuid import logging from typing import Any, Optional -from fastapi import FastAPI, Query +from fastapi import FastAPI, UploadFile, File, Query from pydantic import BaseModel from fastapi.middleware.cors import CORSMiddleware from services.people import get_instance as get_people_service from models.people import People +from agents.extract_people_agent import ExtractPeopleAgent +from utils import obs, ocr api = FastAPI(title="Single People Management and Searching", version="0.1") api.add_middleware( @@ -24,6 +28,53 @@ class BaseResponse(BaseModel): async def ping(): return BaseResponse(error_code=0, error_info="success") +class PostInputRequest(BaseModel): + text: str + +@api.post("/recognition/input") +async def post_input(request: PostInputRequest): + people = extract_people(request.text) + resp = BaseResponse(error_code=0, error_info="success") + resp.data = people.to_dict() + return resp + +@api.post("/recognition/image") +async def post_input_image(image: UploadFile = File(...)): + # 实现上传图片的处理 + # 保存上传的图片文件 + # 生成唯一的文件名 + file_extension = os.path.splitext(image.filename)[1] + unique_filename = f"{uuid.uuid4()}{file_extension}" + + # 确保uploads目录存在 + os.makedirs("uploads", exist_ok=True) + + # 保存文件到对象存储 + file_path = f"uploads/{unique_filename}" + obs_util = obs.get_instance() + obs_util.Put(file_path, await image.read()) + + # 获取对象存储外链 + obs_url = obs_util.Link(file_path) + logging.info(f"obs_url: {obs_url}") + + # 调用OCR处理图片 + ocr_util = ocr.get_instance() + ocr_result = ocr_util.recognize_image_text(obs_url) + logging.info(f"ocr_result: {ocr_result}") + + people = extract_people(ocr_result, obs_url) + resp = BaseResponse(error_code=0, error_info="success") + resp.data = people.to_dict() + return resp + +def extract_people(text: str, cover_link: str = None) -> People: + extra_agent = ExtractPeopleAgent() + people = extra_agent.extract_people_info(text) + people.cover = cover_link + logging.info(f"people: {people}") + return people + class PostPeopleRequest(BaseModel): people: dict diff --git a/uv.lock b/uv.lock index efe4966..3fa7293 100644 --- a/uv.lock +++ b/uv.lock @@ -1186,6 +1186,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, ] +[[package]] +name = "python-multipart" +version = "0.0.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158, upload-time = "2024-12-16T19:45:46.972Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546, upload-time = "2024-12-16T19:45:44.423Z" }, +] + [[package]] name = "pyyaml" version = "6.0.3" @@ -1359,6 +1368,7 @@ dependencies = [ { name = "fastapi" }, { name = "langchain" }, { name = "langchain-openai" }, + { name = "python-multipart" }, { name = "qiniu" }, { name = "sqlalchemy" }, { name = "uvicorn" }, @@ -1371,6 +1381,7 @@ requires-dist = [ { name = "fastapi", specifier = ">=0.118.3" }, { name = "langchain", specifier = "==0.3.27" }, { name = "langchain-openai", specifier = "==0.3.35" }, + { name = "python-multipart", specifier = ">=0.0.20" }, { name = "qiniu", specifier = ">=7.17.0" }, { name = "sqlalchemy", specifier = ">=2.0.44" }, { name = "uvicorn", specifier = ">=0.38.0" },