File size: 3,430 Bytes
cd5aabe 1605267 606732d cd5aabe 606732d 75a5800 cd5aabe 606732d 640e3c9 606732d 787d6e0 46b1977 787d6e0 6507333 fcd684b 787d6e0 44d459b 2c9c1e9 787d6e0 46b1977 6507333 787d6e0 46b1977 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | from enum import Enum
from typing import List, Optional
from pydantic import BaseModel
class ModelType(str, Enum):
"""模型类型枚举"""
HOWCUTEAMI = "howcuteami"
DEEPFACE = "deepface"
HYBRID = "hybrid" # 混合模式:颜值性别用howcuteami,年龄情绪用deepface
class ImageScoreItem(BaseModel):
file_path: str
score: float
is_cropped_face: bool = False
size_bytes: int
size_str: str
last_modified: str
nickname: Optional[str] = None
hostname: Optional[str] = None
region: Optional[str] = None
region_country: Optional[str] = None
class SearchRequest(BaseModel):
keyword: Optional[str] = ""
searchType: Optional[str] = "face"
top_k: Optional[int] = 5
score_threshold: float = 0.0
nickname: Optional[str] = None
region: Optional[str] = None
platform: Optional[str] = None
class ImageSearchRequest(BaseModel):
image: Optional[str] = None # base64编码的图片
searchType: Optional[str] = "face"
top_k: Optional[int] = 5
score_threshold: float = 0.0
nickname: Optional[str] = None
class ImageFileList(BaseModel):
results: List[ImageScoreItem]
count: int
class PagedImageFileList(BaseModel):
results: List[ImageScoreItem]
count: int
page: int
page_size: int
total_pages: int
class CelebrityMatchResponse(BaseModel):
filename: str
display_name: Optional[str] = None
distance: float
similarity: float
confidence: float
face_filename: Optional[str] = None
class CategoryStatItem(BaseModel):
category: str
display_name: str
count: int
class CategoryStatsResponse(BaseModel):
stats: List[CategoryStatItem]
total: int
class RegionStatItem(BaseModel):
region: str
region_country: str
count: int
class RegionStatsResponse(BaseModel):
stats: List[RegionStatItem]
total: int
class UserDeviceItem(BaseModel):
device_id: str
device_type: Optional[str] = None
device_model: Optional[str] = None
os_version: Optional[str] = None
app_version: Optional[str] = None
timezone: Optional[str] = None
region: Optional[str] = None
region_country: Optional[str] = None
language: Optional[str] = None
detection_count: int = 0
created_at: str
updated_at: str
class UserDeviceListResponse(BaseModel):
results: List[UserDeviceItem]
count: int
page: int
page_size: int
total_pages: int
class RankResponse(BaseModel):
success: bool = True
score: float
region_code: Optional[str] = None
region_name: Optional[str] = None
region_rank: int
region_total: int
region_percentile: float
global_rank: int
global_total: int
global_percentile: float
days_limit: int = 90
class LeaderboardItem(BaseModel):
record_id: int
file_path: str = ""
rank: int
score: float
nickname: Optional[str] = None
display_name: str = ""
region_code: Optional[str] = None
region_name: Optional[str] = None
gender: Optional[str] = None
age: Optional[str] = None
avatar_id: int
created_at: Optional[str] = None
updated_at: Optional[str] = None
is_current_user: bool = False
class LeaderboardResponse(BaseModel):
success: bool = True
region_code: Optional[str] = None
region_name: Optional[str] = None
total_records: int
items: List[LeaderboardItem]
days_limit: int = 90
|