edit : imagen -> gemini로 변경, bingimg -> 사용불가 , 벡터검색api 이미지저장이아닌 데이터 전송하는 api 추가 , vactor -> vector 오타 수정

This commit is contained in:
2025-07-30 13:29:24 +09:00
parent 8e28a22825
commit 44bd86562d
45 changed files with 507 additions and 223 deletions

View File

@@ -16,6 +16,7 @@ RESTful API Server
``` ```
gcloud init gcloud init
gcloud auth application-default login gcloud auth application-default login
gcloud config set compute/region asia-east1
``` ```
https://cloud.google.com/docs/authentication/set-up-adc-local-dev-environment?hl=ko https://cloud.google.com/docs/authentication/set-up-adc-local-dev-environment?hl=ko

View File

@@ -1,8 +1,12 @@
class Config: class Config:
def __init__(self): def __init__(self):
self.set_rel() self.set_fermat()
self.use_imagen = True
def set_rel(self): def set_fermat(self):
"""
내부 서버용
"""
self.config = 'rel' self.config = 'rel'
self.remote_folder = "/home/fermat/STORAGE/01.Projects/A2TEC/K_EYEWEAR/02.ML_DATA/Image_generator_result" self.remote_folder = "/home/fermat/STORAGE/01.Projects/A2TEC/K_EYEWEAR/02.ML_DATA/Image_generator_result"
self.sftp_host = "192.168.200.230" self.sftp_host = "192.168.200.230"
@@ -11,6 +15,9 @@ class Config:
self.sftp_pw = "1234" self.sftp_pw = "1234"
def set_dev(self): def set_dev(self):
"""
개발용
"""
self.config = 'dev' self.config = 'dev'
self.remote_folder = "/home/fermat/project/FM_TEST_REST_SERVER/result" self.remote_folder = "/home/fermat/project/FM_TEST_REST_SERVER/result"
self.sftp_host = "192.168.200.231" self.sftp_host = "192.168.200.231"
@@ -22,6 +29,21 @@ class Config:
if not os.path.exists(self.remote_folder): if not os.path.exists(self.remote_folder):
os.makedirs(self.remote_folder) os.makedirs(self.remote_folder)
def set_ict(self):
pass
# self.config = 'rel'
# self.remote_folder = "/home/fermat/STORAGE/01.Projects/A2TEC/K_EYEWEAR/02.ML_DATA/Image_generator_result"
# self.sftp_host = "192.168.200.230"
# self.sftp_port = 22
# self.sftp_id = "fermat"
# self.sftp_pw = "1234"
def toggle_imagen(self):
if self.use_imagen:
self.use_imagen = False
else:
self.use_imagen = True
rest_config = Config() rest_config = Config()
# rest_config.set_dev() rest_config.set_dev()
rest_config.toggle_imagen()

View File

@@ -56,7 +56,7 @@ Implementation
""" """
def get_models(index_type, model_type): def get_models(index_type, model_type):
from vactor_rest.app import models as M from vector_rest.app import models as M
model = None model = None

View File

@@ -57,9 +57,9 @@ class BingArtGenerator:
else: else:
return None return None
def link_to_img(self, img_links:list): def link_to_img_remote(self, img_links:list):
""" """
이미지 링크로 이미지 파일 저장 이미지 링크로 이미지 파일 원격지에 저장
""" """
jpeg_index = 1 jpeg_index = 1
@@ -80,6 +80,20 @@ class BingArtGenerator:
return 0 return 0
else: else:
self.link_to_img(img_links=image_links) self.link_to_img_remote(img_links=image_links)
return len(image_links) return len(image_links)
def get_query_image(self,prompt):
create_time = D.date_file_name()
image_links = self.get_image_links(prompt,1)
if image_links == None:
return 0
else:
image = image_links[0]
query_path = os.path.join(TEMP_FOLDER,f"query_bingarg_{create_time}.png")
urllib.request.urlretrieve(image, query_path)
return query_path

View File

@@ -1,5 +1,7 @@
import os import os
import shutil import shutil
import torch
import faiss
from custom_apps.faiss_imagenet.utils import preprocessing, preprocessing_quary, normalize, get_dataset_list from custom_apps.faiss_imagenet.utils import preprocessing, preprocessing_quary, normalize, get_dataset_list
from custom_apps.faiss_imagenet.const import * from custom_apps.faiss_imagenet.const import *
@@ -15,17 +17,29 @@ def search_idxs(image_path,dataset_bin=DATASET_BIN,index_type="hnsw",search_num=
DIM = 1280 DIM = 1280
# res = faiss.StandardGpuResources()
# __res = faiss.StandardGpuResources()
dataset_fvces, dataset_index = preprocessing(DIM,dataset_bin,index_type) dataset_fvces, dataset_index = preprocessing(DIM,dataset_bin,index_type)
org_fvces, org_index = preprocessing_quary(DIM,image_path,index_type) org_fvces, org_index = preprocessing_quary(DIM,image_path,index_type)
# cpu -> gpu
# gpu_idx = faiss.index_cpu_to_gpu_multiple_py([res], 0, dataset_index)
# __gpu_idx = faiss.index_cpu_to_gpu_multiple_py([__res], 0, org_index)
dists, idxs = dataset_index.search(normalize(org_fvces), search_num) dists, idxs = dataset_index.search(normalize(org_fvces), search_num)
# print(dists[0])
# print(idxs[0])
index_image_save(image_path, dists[0], idxs[0]) index_image_save(image_path, dists[0], idxs[0])
# del dataset_fvces, dataset_index, org_fvces, org_index, dists, idxs
# del res, __res, gpu_idx, __gpu_idx
# torch.cuda.empty_cache()
# import gc
# gc.collect()
def index_image_save(query_image_path, dists, idxs): def index_image_save(query_image_path, dists, idxs):
directory_path, file = os.path.split(query_image_path) directory_path, file = os.path.split(query_image_path)
_name, extension = os.path.splitext(file) _name, extension = os.path.splitext(file)

View File

@@ -0,0 +1,40 @@
import os
import time
from google import genai
from google.genai import types
from PIL import Image
from io import BytesIO
from main_rest.app.utils.date_utils import D
from const import TEMP_FOLDER
def gemini_image(prompt, folder=None):
from custom_logger.main_log import main_logger as LOG
image_path = ''
client = genai.Client(api_key="AIzaSyB7tu67y9gOkJkpQtvI5OAYSzUzwv9qwnE")
response = client.models.generate_content(
model="gemini-2.0-flash-preview-image-generation",
contents=prompt,
config=types.GenerateContentConfig(
response_modalities=['TEXT', 'IMAGE']
)
)
if folder == None:
folder = TEMP_FOLDER
if not os.path.exists(folder):
os.makedirs(folder)
for part in response.candidates[0].content.parts:
if part.inline_data is not None:
image = Image.open(BytesIO((part.inline_data.data)))
image_path = os.path.join(folder,f"gemini_{D.date_file_name()}_query.png")
image.save(image_path)
LOG.info(f"image generate : {image_path}")
time.sleep(2)
return image_path

View File

@@ -15,6 +15,7 @@ class ImagenConst:
project_id = "glasses-imagen" project_id = "glasses-imagen"
location = "asia-east1" location = "asia-east1"
model = "imagen-3.0-generate-001" model = "imagen-3.0-generate-001"
# model = "imagen-3.0-fast-generate-001"
def imagen_generate_image(prompt,download_count=1): def imagen_generate_image(prompt,download_count=1):

View File

@@ -1,6 +1,6 @@
class CookieManager: class CookieManager:
DEFAULT_COOKIE = "19S_ux18UhHzxHMsY5gTYwqk2YjYahwxssgJyx0AybuAjDa_kZKWFauqMSrtb1a80s89VjmLwKWIGhvpZxLOzkwcMXAuShkgFwGSVlD8ayI7qgQiCabE9-UFByw4QJ_ZSAnOnskn5iPydk4vaZZEayTR--u7-mVglsaANK6rGOQPeu8q-Sa6cjVCUQR9kkjEtz-J4wf2MQ6inXuC41IbCi8QwmZyHkwxOy6U6CqPiREg" DEFAULT_COOKIE = "1dcelksYDmBzN1R2heBkdpHpku-E2Qr8KAA4bToiSqFBtLUDGPMgKXrpc0X_oVhSCzcX3rk3kB8GgwILUNdvrhgO9Zu_BgcpromvlpjUg1jukhL6v3SBE-YOBQqzBC6OanguFOfAAlFJjB7ZJBzoPQzdrKU7L8yMQZZ-BAsfr18M6MnWy1aaEWljSmOA7_fTql5RcjCPNk_FZBeFXolnOIdNfLqGIFWsPKM8nNZVXNSs"
def __init__(self): def __init__(self):
self.cookie = self.DEFAULT_COOKIE self.cookie = self.DEFAULT_COOKIE

View File

@@ -8,7 +8,7 @@ vactor_logger = None
_now = datetime.datetime.now() _now = datetime.datetime.now()
LOGGER_NAME = 'vactor' LOGGER_NAME = 'vector'
LOGGER_FILE_NAME = f'{_now.strftime("%Y-%m-%d %H_%M_%S")}_{LOGGER_NAME}.log' LOGGER_FILE_NAME = f'{_now.strftime("%Y-%m-%d %H_%M_%S")}_{LOGGER_NAME}.log'
LOGGER_LEVEL = logging.INFO LOGGER_LEVEL = logging.INFO

View File

@@ -40,6 +40,14 @@ async def lifespan(app: FastAPI):
# When service starts. # When service starts.
LOG.info(f"REST start (port : {conf().REST_SERVER_PORT})") LOG.info(f"REST start (port : {conf().REST_SERVER_PORT})")
import os
import const
if os.path.exists(const.TEMP_FOLDER):
for _file in os.scandir(const.TEMP_FOLDER):
os.remove(_file)
LOG.info(f"temp folder clean")
yield yield
# When service is stopped. # When service is stopped.

View File

@@ -600,16 +600,16 @@ class BingCookieSetReq(BaseModel):
class VactorImageSearchReq(BaseModel): class VactorImageSearchReq(BaseModel):
""" """
### [Request] vactor image search request ### [Request] vector image search request
""" """
prompt : str = Field(description='프롬프트', example='검은색 안경') prompt : str = Field(description='프롬프트', example='검은색 안경')
indexType : str = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) indexType : str = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2)
searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4) searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4)
class VactorImageSearchVitReq(BaseModel): class VectorImageSearchVitReq(BaseModel):
""" """
### [Request] vactor image search vit ### [Request] vector image search vit
""" """
prompt : str = Field(description='프롬프트', example='검은색 안경') prompt : str = Field(description='프롬프트', example='검은색 안경')
modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14) modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14)
@@ -617,14 +617,23 @@ class VactorImageSearchVitReq(BaseModel):
searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4) searchNum : int = Field(4, description='검색결과 이미지 갯수', example=4)
class VactorImageSearchVitReportReq(BaseModel): class VectorImageSearchVitDataReq(VectorImageSearchVitReq):
""" """
### [Request] vactor image search vit request ### [Request] vector image search vit data
"""
querySend: bool = Field(True, description='쿼리 이미지 전송 여부', example=True)
class VectorImageSearchVitReportReq(BaseModel):
"""
### [Request] vector image search vit request
""" """
prompt : str = Field(description='프롬프트', example='검은색 안경') prompt : str = Field(description='프롬프트', example='검은색 안경')
modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14) modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14)
indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2) indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2)
class VectorImageResult(BaseModel):
image : str = Field("", description='이미지 데이터', example='')
percents: float = Field(0.0, description='percents 값', example='')
#=============================================================================== #===============================================================================
#=============================================================================== #===============================================================================
@@ -673,3 +682,29 @@ class BingCookieSetRes(ResponseBase):
BingCookieSetRes.error = None BingCookieSetRes.error = None
BingCookieSetRes.currentCookie = current_cookie BingCookieSetRes.currentCookie = current_cookie
return BingCookieSetRes return BingCookieSetRes
class VectorImageSerachDataRes(ResponseBase):
"""
### vector image data response
"""
queryImage : str = Field("", description='쿼리 이미지', example="")
vectorResult : List[VectorImageResult] = Field([], description='벡터 검색 결과', example=[])
@staticmethod
def set_error(error,vector_result=[],query_img=""):
ImageGenerateRes.result = False
ImageGenerateRes.error = str(error)
ImageGenerateRes.vectorResult = vector_result
ImageGenerateRes.queryImage = query_img
return ImageGenerateRes
@staticmethod
def set_message(vector_result,query_img=""):
ImageGenerateRes.result = True
ImageGenerateRes.error = None
ImageGenerateRes.vectorResult = vector_result
ImageGenerateRes.queryImage = query_img
return ImageGenerateRes

View File

@@ -9,7 +9,7 @@
@brief: services api @brief: services api
""" """
import requests, json, traceback, os import requests, json, traceback, os, shutil
from fastapi import APIRouter, Depends, Body from fastapi import APIRouter, Depends, Body
from starlette.requests import Request from starlette.requests import Request
from typing import Annotated, List from typing import Annotated, List
@@ -17,109 +17,111 @@ from typing import Annotated, List
from main_rest.app.common import consts from main_rest.app.common import consts
from main_rest.app import models as M from main_rest.app import models as M
from main_rest.app.utils.date_utils import D from main_rest.app.utils.date_utils import D
from main_rest.app.utils.parsing_utils import image_to_base64_string
from custom_logger.main_log import main_logger as LOG from custom_logger.main_log import main_logger as LOG
from custom_apps.bingimagecreator.utils import DallEArgument,dalle3_generate_image from custom_apps.bingimagecreator.utils import DallEArgument,dalle3_generate_image
from custom_apps.bingart.bingart import BingArtGenerator from custom_apps.bingart.bingart import BingArtGenerator
from custom_apps.imagen.custom_imagen import imagen_generate_image, imagen_generate_image_path, imagen_generate_temp_image_path from custom_apps.imagen.custom_imagen import imagen_generate_image, imagen_generate_image_path, imagen_generate_temp_image_path
from main_rest.app.utils.parsing_utils import download_range
from custom_apps.utils import cookie_manager from custom_apps.utils import cookie_manager
from custom_apps.gemini.main import gemini_image
from main_rest.app.utils.parsing_utils import download_range
from utils.custom_sftp import sftp_client from utils.custom_sftp import sftp_client
from config import rest_config from config import rest_config
from const import TEMP_FOLDER
router = APIRouter(prefix="/services") router = APIRouter(prefix="/services")
@router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes) # @router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes)
async def bing_cookie_set(request: Request, request_body_info: M.BingCookieSetReq): # async def bing_cookie_set(request: Request, request_body_info: M.BingCookieSetReq):
""" # """
## Bing cookie set # ## Bing cookie set
> 쿠키정보 set # > 쿠키정보 set
## 정보 # ## 정보
> cookie 값이 빈 값일경우 쿠키정보를 set 하지 않고 현재 쿠키값 return 함 # > cookie 값이 빈 값일경우 쿠키정보를 set 하지 않고 현재 쿠키값 return 함
> cookie 값이 정상 쿠키 인지는 확인안함 # > cookie 값이 정상 쿠키 인지는 확인안함
""" # """
response = M.BingCookieSetRes() # response = M.BingCookieSetRes()
try: # try:
if len(request_body_info.cookie) == 0: # if len(request_body_info.cookie) == 0:
pass # pass
else: # else:
cookie_manager.set_cookie(request_body_info.cookie) # cookie_manager.set_cookie(request_body_info.cookie)
return response.set_message(current_cookie=cookie_manager.get_cookie()) # return response.set_message(current_cookie=cookie_manager.get_cookie())
except Exception as e: # except Exception as e:
LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
return response.set_error(e,current_cookie=cookie_manager.get_cookie()) # return response.set_error(e,current_cookie=cookie_manager.get_cookie())
@router.post("/imageGenerate/bingimg", summary="이미지 생성(AI) - bing image generator (DALL-E 3)", response_model=M.ImageGenerateRes) # @router.post("/imageGenerate/bingimg", summary="이미지 생성(AI) - bing image generator (DALL-E 3)", response_model=M.ImageGenerateRes)
async def bing_img_generate(request: Request, request_body_info: M.ImageGenerateReq): # async def bing_img_generate(request: Request, request_body_info: M.ImageGenerateReq):
""" # """
## 이미지 생성(AI) - bing image generator (DALL-E 3) # ## 이미지 생성(AI) - bing image generator (DALL-E 3)
> bing image generator를 이용하여 이미지 생성 # > bing image generator를 이용하여 이미지 생성
### Requriements # ### Requriements
## 정보 # ## 정보
> 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함 # > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함
> *동작 안함.
""" # """
response = M.ImageGenerateRes() # response = M.ImageGenerateRes()
try: # try:
if not download_range(request_body_info.downloadCount): # if not download_range(request_body_info.downloadCount):
raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})") # raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})")
args = DallEArgument( # args = DallEArgument(
prompt=request_body_info.prompt, # prompt=request_body_info.prompt,
download_count=request_body_info.downloadCount # download_count=request_body_info.downloadCount
) # )
info = dalle3_generate_image(args) # info = dalle3_generate_image(args)
if info.get_error_messages(): # if info.get_error_messages():
error_message = f"파일생성 error: {info.get_error_messages()}" # error_message = f"파일생성 error: {info.get_error_messages()}"
LOG.error(error_message) # LOG.error(error_message)
return response.set_error(error=error_message, img_len=info.get_counter()) # return response.set_error(error=error_message, img_len=info.get_counter())
return response.set_message(img_len=info.get_counter()) # return response.set_message(img_len=info.get_counter())
except Exception as e: # except Exception as e:
LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
return response.set_error(e) # return response.set_error(e)
@router.post("/imageGenerate/bingart", summary="이미지 생성(AI) - bing art (DALL-E 3)", response_model=M.ImageGenerateRes) # @router.post("/imageGenerate/bingart", summary="이미지 생성(AI) - bing art (DALL-E 3)", response_model=M.ImageGenerateRes)
async def bing_art(request: Request, request_body_info: M.ImageGenerateReq): # async def bing_art(request: Request, request_body_info: M.ImageGenerateReq):
""" # """
## 이미지 생성(AI) - bing art (DALL-E 3) # ## 이미지 생성(AI) - bing art (DALL-E 3)
> bing art를 이용하여 이미지 생성 # > bing art를 이용하여 이미지 생성
### Requriements # ### Requriements
## 정보 # ## 정보
> 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함 # > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함
> *동작 안함. # > *동작 안함.
""" # """
response = M.ImageGenerateRes() # response = M.ImageGenerateRes()
try: # try:
if not download_range(request_body_info.downloadCount): # if not download_range(request_body_info.downloadCount):
raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})") # raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})")
bing_art = BingArtGenerator() # bing_art = BingArtGenerator()
info = bing_art.get_images(prompt=request_body_info.prompt,image_len=request_body_info.downloadCount) # info = bing_art.get_images(prompt=request_body_info.prompt,image_len=request_body_info.downloadCount)
return response.set_message(img_len=info) # return response.set_message(img_len=info)
except Exception as e: # except Exception as e:
LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
return response.set_error(e) # return response.set_error(e)
@router.post("/imageGenerate/imagen", summary="이미지 생성(AI) - imagen", response_model=M.ImageGenerateRes) @router.post("/imageGenerate/imagen", summary="이미지 생성(AI) - imagen", response_model=M.ImageGenerateRes)
async def imagen(request: Request, request_body_info: M.ImageGenerateReq): async def imagen(request: Request, request_body_info: M.ImageGenerateReq):
@@ -127,78 +129,102 @@ async def imagen(request: Request, request_body_info: M.ImageGenerateReq):
## 이미지 생성(AI) - imagen ## 이미지 생성(AI) - imagen
> imagen AI를 이용하여 이미지 생성 > imagen AI를 이용하여 이미지 생성
### Requriements
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
> - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함.
""" """
# imagen 사용중단 gemini로 변경
response = M.ImageGenerateRes() response = M.ImageGenerateRes()
try: try:
if not download_range(request_body_info.downloadCount): if not download_range(request_body_info.downloadCount):
raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})") raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})")
img_length = imagen_generate_image(prompt=request_body_info.prompt, # NOTE(JWKIM) : imagen 사용 중단
download_count=request_body_info.downloadCount # img_length = imagen_generate_image(prompt=request_body_info.prompt,
) # download_count=request_body_info.downloadCount
# )
temp_image_path = gemini_image(request_body_info.prompt)
_remote_folder = os.path.join(rest_config.remote_folder,"imagen")
return response.set_message(img_len=img_length) # remote save
sftp_client.remote_copy_data(
temp_image_path,
os.path.join(_remote_folder,f"imagen_{request_body_info.prompt}_{1}_{D.date_file_name()}.png"))
# Clean up temporary files
if 'temp_image_path' in locals():
if os.path.exists(temp_image_path):
os.remove(temp_image_path)
del temp_image_path
return response.set_message(img_len=1)
except Exception as e: except Exception as e:
LOG.error(traceback.format_exc()) LOG.error(traceback.format_exc())
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
return response.set_error(error=e) return response.set_error(error=e)
@router.post("/vactorImageSearch/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase) # @router.post("/vactorImageSearch/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase)
async def vactor_imagenet(request: Request, request_body_info: M.VactorImageSearchReq): # async def vactor_imagenet(request: Request, request_body_info: M.VactorImageSearchReq):
""" # """
## 벡터 이미지 검색 - imagen # ## 벡터 이미지 검색 - imagen
> imagen AI를 이용하여 이미지 생성 후 vactor 검색 # > imagen AI를 이용하여 이미지 생성 후 vector 검색
### Requriements # ### Requriements
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) # > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
> - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함. # > - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함.
""" # """
response = M.ResponseBase() # # NOTE(JWKIM) : GPU 메모리 이슈로 사용 중단
try: # response = M.ResponseBase()
if request_body_info.indexType not in [M.IndexType.hnsw, M.IndexType.l2]: # try:
raise Exception(f"indexType is hnsw or l2 (current value = {request_body_info.indexType})") # if request_body_info.indexType not in [M.IndexType.hnsw, M.IndexType.l2]:
# raise Exception(f"indexType is hnsw or l2 (current value = {request_body_info.indexType})")
img_path = imagen_generate_image_path(image_prompt=request_body_info.prompt) # _temp_folder = f"{request_body_info.prompt}_{D.date_file_name()}"
vactor_request_data = {'query_image_path' : img_path, # # img_path = imagen_generate_image_path(image_prompt=request_body_info.prompt) #imagen
'index_type' : request_body_info.indexType, # img_path = gemini_image(request_body_info.prompt, os.path.join(TEMP_FOLDER, _temp_folder)) #gemini
'search_num' : request_body_info.searchNum}
vactor_response = requests.post('http://localhost:51002/api/services/faiss/vactor/search/imagenet', data=json.dumps(vactor_request_data))
if vactor_response.status_code != 200: # vector_request_data = {'query_image_path' : img_path,
raise Exception(f"response error: {json.loads(vactor_response.text)['error']}") # 'index_type' : request_body_info.indexType,
# 'search_num' : request_body_info.searchNum}
# vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/imagenet', data=json.dumps(vector_request_data))
if json.loads(vactor_response.text)["error"] != None: # if vector_response.status_code != 200:
raise Exception(f"vactor error: {json.loads(vactor_response.text)['error']}") # raise Exception(f"response error: {json.loads(vector_response.text)['error']}")
# remote # if json.loads(vector_response.text)["error"] != None:
_directory_path, _file = os.path.split(img_path) # raise Exception(f"vector error: {json.loads(vector_response.text)['error']}")
_base_bame = os.path.basename(_directory_path)
# remote 폴더 생성 # # remote
sftp_client.remote_mkdir(os.path.join(rest_config.remote_folder, _base_bame)) # _directory_path, _file = os.path.split(img_path)
# remote 폴더에 이미지 저장 # # remote 폴더 생성
for i in os.listdir(_directory_path): # sftp_client.remote_mkdir(os.path.join(rest_config.remote_folder, _temp_folder))
sftp_client.remote_copy_data(local_path=os.path.join(_directory_path, i), remote_path=os.path.join(rest_config.remote_folder, _base_bame, i))
return response.set_message() # # remote 폴더에 이미지 저장
# for i in os.listdir(_directory_path):
# sftp_client.remote_copy_data(local_path=os.path.join(_directory_path, i),
# remote_path=os.path.join(rest_config.remote_folder, _temp_folder, i))
# shutil.rmtree(_directory_path)
# return response.set_message()
except Exception as e: # except Exception as e:
LOG.error(traceback.format_exc()) # LOG.error(traceback.format_exc())
return response.set_error(error=e) # return response.set_error(error=e)
@router.post("/vactorImageSearch/vit/imageGenerate/imagen", summary="벡터 이미지 검색(clip-vit) - imagen", response_model=M.ResponseBase) @router.post("/vactorImageSearch/vit/imageGenerate/imagen", summary="벡터 이미지 검색(clip-vit) - imagen", response_model=M.ResponseBase)
async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSearchVitReq): async def vactor_vit(request: Request, request_body_info: M.VectorImageSearchVitReq):
""" """
## 벡터 이미지 검색(clip-vit) - imagen ## 벡터 이미지 검색(clip-vit) - imagen
> imagen AI를 이용하여 이미지 생성 후 vactor 검색 그후 결과 이미지 생성 > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지 생성
### Requriements ### Requriements
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
@@ -219,14 +245,15 @@ async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSe
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]: if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})") raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
query_image_path = gemini_image(request_body_info.prompt) #gemini
vector_request_data = {'query_image_path' : query_image_path, vector_request_data = {'query_image_path' : query_image_path,
'index_type' : request_body_info.indexType, 'index_type' : request_body_info.indexType,
'model_type' : request_body_info.modelType, 'model_type' : request_body_info.modelType,
'search_num' : request_body_info.searchNum} 'search_num' : request_body_info.searchNum}
vector_response = requests.post('http://localhost:51002/api/services/faiss/vactor/search/vit', data=json.dumps(vector_request_data)) vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
vector_response_dict = json.loads(vector_response.text) vector_response_dict = json.loads(vector_response.text)
@@ -234,7 +261,7 @@ async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSe
raise Exception(f"response error: {vector_response_dict['error']}") raise Exception(f"response error: {vector_response_dict['error']}")
if vector_response_dict["error"] != None: if vector_response_dict["error"] != None:
raise Exception(f"vactor error: {vector_response_dict['error']}") raise Exception(f"vector error: {vector_response_dict['error']}")
result_image_paths = vector_response_dict.get('img_list').get('result_image_paths') result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
result_percents = vector_response_dict.get('img_list').get('result_percents') result_percents = vector_response_dict.get('img_list').get('result_percents')
@@ -268,11 +295,91 @@ async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSe
return response.set_error(error=e) return response.set_error(error=e)
@router.post("/vactorImageSearch/vit/imageGenerate/imagen/data", summary="벡터 이미지 검색(clip-vit) - imagen(data)", response_model=M.VectorImageSerachDataRes)
async def vactor_vit_report_data(request: Request, request_body_info: M.VectorImageSearchVitDataReq):
"""
## 벡터 이미지 검색(clip-vit) - imagen
> imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지데이터 return
### Requriements
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
### options
> - modelType -> b32,b16,l14,l14_336
> - indexType -> l2,cos
"""
response = M.VectorImageSerachDataRes()
query_image_data = ''
try:
if not download_range(request_body_info.searchNum, max=10):
raise Exception(f"downloadCound is invalid (current value = {request_body_info.searchNum})")
if request_body_info.modelType not in [M.VitModelType.b32, M.VitModelType.b16, M.VitModelType.l14, M.VitModelType.l14_336]:
raise Exception(f"modelType is invalid (current value = {request_body_info.modelType})")
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
# query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
query_image_path = gemini_image(request_body_info.prompt) #gemini
vector_request_data = {'query_image_path' : query_image_path,
'index_type' : request_body_info.indexType,
'model_type' : request_body_info.modelType,
'search_num' : request_body_info.searchNum}
vector_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit', data=json.dumps(vector_request_data))
vector_response_dict = json.loads(vector_response.text)
if vector_response.status_code != 200:
raise Exception(f"response error: {vector_response_dict['error']}")
if vector_response_dict["error"] != None:
raise Exception(f"vector error: {vector_response_dict['error']}")
result_image_paths = vector_response_dict.get('img_list').get('result_image_paths')
result_percents = vector_response_dict.get('img_list').get('result_percents')
# 이미지 데이터 생성
vector_image_results = []
for img, percents in zip(result_image_paths, result_percents):
b64_data = image_to_base64_string(img)
float_percent = float(percents)
info = M.VectorImageResult(image=b64_data,percents=float_percent)
vector_image_results.append(info)
if request_body_info.querySend:
query_image_data = image_to_base64_string(query_image_path)
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
return response.set_message(vector_result=vector_image_results,query_img=query_image_data)
except Exception as e:
LOG.error(traceback.format_exc())
# Clean up temporary files
if 'query_image_path' in locals():
if os.path.exists(query_image_path):
os.remove(query_image_path)
del query_image_path
return response.set_error(error=e)
@router.post("/vactorImageSearch/vit/imageGenerate/imagen/report", summary="벡터 이미지 검색(clip-vit) - imagen, report 생성", response_model=M.ResponseBase) @router.post("/vactorImageSearch/vit/imageGenerate/imagen/report", summary="벡터 이미지 검색(clip-vit) - imagen, report 생성", response_model=M.ResponseBase)
async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSearchVitReportReq): async def vactor_vit_report(request: Request, request_body_info: M.VectorImageSearchVitReportReq):
""" """
## 벡터 이미지 검색(clip-vit) - imagen, report 생성 ## 벡터 이미지 검색(clip-vit) - imagen, report 생성
> imagen AI를 이용하여 이미지 생성 후 vactor 검색 그후 종합결과 이미지 생성 > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 종합결과 이미지 생성
### Requriements ### Requriements
> - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux)
@@ -290,7 +397,8 @@ async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSe
if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]: if request_body_info.indexType not in [M.VitIndexType.cos, M.VitIndexType.l2]:
raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})") raise Exception(f"indexType is invalid (current value = {request_body_info.indexType})")
query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) # query_image_path = imagen_generate_temp_image_path(image_prompt=request_body_info.prompt) #imagen
query_image_path = gemini_image(request_body_info.prompt) #gemini
report_image_path = f"{os.path.splitext(query_image_path)[0]}_report.png" report_image_path = f"{os.path.splitext(query_image_path)[0]}_report.png"
vactor_request_data = {'query_image_path' : query_image_path, vactor_request_data = {'query_image_path' : query_image_path,
@@ -298,13 +406,13 @@ async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSe
'model_type' : request_body_info.modelType, 'model_type' : request_body_info.modelType,
'report_path' : report_image_path} 'report_path' : report_image_path}
vactor_response = requests.post('http://localhost:51002/api/services/faiss/vactor/search/vit/report', data=json.dumps(vactor_request_data)) vactor_response = requests.post('http://localhost:51002/api/services/faiss/vector/search/vit/report', data=json.dumps(vactor_request_data))
if vactor_response.status_code != 200: if vactor_response.status_code != 200:
raise Exception(f"response error: {json.loads(vactor_response.text)['error']}") raise Exception(f"response error: {json.loads(vactor_response.text)['error']}")
if json.loads(vactor_response.text)["error"] != None: if json.loads(vactor_response.text)["error"] != None:
raise Exception(f"vactor error: {json.loads(vactor_response.text)['error']}") raise Exception(f"vector error: {json.loads(vactor_response.text)['error']}")
# remote 폴더에 이미지 저장 # remote 폴더에 이미지 저장
sftp_client.remote_copy_data(local_path=report_image_path, sftp_client.remote_copy_data(local_path=report_image_path,

View File

@@ -1,5 +1,9 @@
import os
import base64
from const import ILLEGAL_FILE_NAME from const import ILLEGAL_FILE_NAME
def prompt_to_filenames(prompt): def prompt_to_filenames(prompt):
""" """
prompt 에 사용할 수 없는 문자가 있으면 '_' 로 치환 prompt 에 사용할 수 없는 문자가 있으면 '_' 로 치환
@@ -23,3 +27,35 @@ def download_range(download_count:int,max=4):
return False return False
def image_to_base64_string(image_path: str) -> str:
"""
이미지 파일 경로를 입력받아 해당 이미지를 Base64 문자열로 인코딩하여 반환합니다.
Args:
image_path (str): Base64로 변환할 이미지 파일의 경로 (예: "path/to/your/image.png").
Returns:
str: 인코딩된 Base64 문자열. 이미지 파일을 찾을 수 없거나 읽을 수 없는 경우 빈 문자열을 반환합니다.
Raises:
FileNotFoundError: 지정된 이미지 경로에 파일이 존재하지 않을 때 발생합니다.
IOError: 파일을 읽는 도중 오류가 발생할 때 발생합니다.
"""
if not os.path.exists(image_path):
raise FileNotFoundError(f"Image file not found at: {image_path}")
try:
with open(image_path, "rb") as image_file:
# 이미지 파일을 이진(binary) 모드로 읽습니다.
binary_data = image_file.read()
# 이진 데이터를 Base64로 인코딩합니다.
base64_encoded_data = base64.b64encode(binary_data)
# 바이트 문자열을 UTF-8 디코딩하여 일반 문자열로 반환합니다.
base64_string = base64_encoded_data.decode('utf-8')
return base64_string
except IOError as e:
raise IOError(f"Error reading image file {image_path}: {e}")
except Exception as e:
# 그 외 예외 처리
raise Exception(f"An unexpected error occurred: {e}")

View File

@@ -15,21 +15,25 @@ email-validator
requests requests
#imagen #imagen
google-cloud-aiplatform # google-cloud-aiplatform
Pillow # Pillow
# #bing img # #bing img
aiohttp # aiohttp
regex # regex
requests # requests
httpx # httpx
nest_asyncio # nest_asyncio
# #bing art # # #bing art
bingart==1.1.0 # bingart==1.1.0
#DALL-E 3 #DALL-E 3
# openai # openai
# gemini
google-genai
pillow
# SFTP # SFTP
paramiko paramiko

View File

@@ -1,6 +0,0 @@
import uvicorn
from vactor_rest.app.common.config import conf
if __name__ == '__main__':
uvicorn.run('vactor_rest.app.main:app', host='0.0.0.0', port=conf().REST_SERVER_PORT, reload=True)

6
rest_vector.py Normal file
View File

@@ -0,0 +1,6 @@
import uvicorn
from vector_rest.app.common.config import conf
if __name__ == '__main__':
uvicorn.run('vector_rest.app.main:app', host='0.0.0.0', port=conf().REST_SERVER_PORT, reload=True)

View File

@@ -12,8 +12,8 @@
from dataclasses import dataclass from dataclasses import dataclass
from os import path, environ from os import path, environ
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app.models import UserInfo from vector_rest.app.models import UserInfo
base_dir = path.dirname(path.dirname(path.dirname(path.abspath(__file__)))) base_dir = path.dirname(path.dirname(path.dirname(path.abspath(__file__))))

View File

@@ -12,11 +12,11 @@
# SUPPORT PROJECT # SUPPORT PROJECT
SUPPORT_PROJECT_BASIC = 'PROJECT_BASIC' SUPPORT_PROJECT_BASIC = 'PROJECT_BASIC'
PROJECT_NAME = 'FERMAT-TEST(Vactor REST API)' PROJECT_NAME = 'FERMAT-TEST(Vector REST API)'
SW_TITLE= f'{PROJECT_NAME} - REST API' SW_TITLE= f'{PROJECT_NAME} - REST API'
SW_VERSION = '0.1.0' SW_VERSION = '0.1.0'
SW_DESCRIPTION = f''' SW_DESCRIPTION = f'''
### FERMAT-TEST(Vactor REST API) REST API ### FERMAT-TEST(Vector REST API) REST API
## API 이용법 ## API 이용법
- 개별 API 설명과 Request/Response schema 참조 - 개별 API 설명과 Request/Response schema 참조

View File

@@ -126,8 +126,8 @@ Base = declarative_base()
# NOTE(hsj100): ADMINISTRATOR # NOTE(hsj100): ADMINISTRATOR
def create_admin(db_session): def create_admin(db_session):
import bcrypt import bcrypt
from vactor_rest.app.database.schema import Users from vector_rest.app.database.schema import Users
from vactor_rest.app.common.consts import ADMIN_INIT_ACCOUNT_INFO from vector_rest.app.common.consts import ADMIN_INIT_ACCOUNT_INFO
session = db_session() session = db_session()

View File

@@ -16,10 +16,10 @@ from sqlalchemy import func, desc
from fastapi import APIRouter, Depends, Body from fastapi import APIRouter, Depends, Body
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from vactor_rest.app import models as M from vector_rest.app import models as M
from vactor_rest.app.database.conn import Base, db from vector_rest.app.database.conn import Base, db
from vactor_rest.app.database.schema import Users, UserLog from vector_rest.app.database.schema import Users, UserLog
from vactor_rest.app.utils.extra import query_to_groupby, query_to_groupby_date from vector_rest.app.utils.extra import query_to_groupby, query_to_groupby_date
def get_month_info_list(start: datetime, end: datetime): def get_month_info_list(start: datetime, end: datetime):

View File

@@ -21,9 +21,9 @@ from sqlalchemy import (
) )
from sqlalchemy.orm import Session, relationship from sqlalchemy.orm import Session, relationship
from vactor_rest.app.database.conn import Base, db from vector_rest.app.database.conn import Base, db
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
from vactor_rest.app.models import ( from vector_rest.app.models import (
SexType, SexType,
UserType, UserType,
MemberType, MemberType,

View File

@@ -1,4 +1,4 @@
from vactor_rest.app.common.consts import MAX_API_KEY, MAX_API_WHITELIST from vector_rest.app.common.consts import MAX_API_KEY, MAX_API_WHITELIST
class StatusCode: class StatusCode:

View File

@@ -20,13 +20,13 @@ from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware from starlette.middleware.base import BaseHTTPMiddleware
from starlette.middleware.cors import CORSMiddleware from starlette.middleware.cors import CORSMiddleware
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app.database.conn import db from vector_rest.app.database.conn import db
from vactor_rest.app.common.config import conf from vector_rest.app.common.config import conf
from vactor_rest.app.middlewares.token_validator import access_control from vector_rest.app.middlewares.token_validator import access_control
from vactor_rest.app.middlewares.trusted_hosts import TrustedHostMiddleware from vector_rest.app.middlewares.trusted_hosts import TrustedHostMiddleware
from vactor_rest.app.routes import dev, index, auth, users, services from vector_rest.app.routes import dev, index, auth, users, services
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from custom_logger.vactor_log import vactor_logger as LOG from custom_logger.vactor_log import vactor_logger as LOG

View File

@@ -12,19 +12,19 @@ from jwt.exceptions import ExpiredSignatureError, DecodeError
from starlette.requests import Request from starlette.requests import Request
from starlette.responses import JSONResponse from starlette.responses import JSONResponse
from vactor_rest.app.common.consts import EXCEPT_PATH_LIST, EXCEPT_PATH_REGEX from vector_rest.app.common.consts import EXCEPT_PATH_LIST, EXCEPT_PATH_REGEX
from vactor_rest.app.database.conn import db from vector_rest.app.database.conn import db
from vactor_rest.app.database.schema import Users, ApiKeys from vector_rest.app.database.schema import Users, ApiKeys
from vactor_rest.app.errors import exceptions as ex from vector_rest.app.errors import exceptions as ex
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app.common.config import conf from vector_rest.app.common.config import conf
from vactor_rest.app.errors.exceptions import APIException, SqlFailureEx, APIQueryStringEx from vector_rest.app.errors.exceptions import APIException, SqlFailureEx, APIQueryStringEx
from vactor_rest.app.models import UserToken from vector_rest.app.models import UserToken
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
from vactor_rest.app.utils.logger import api_logger from vector_rest.app.utils.logger import api_logger
from vactor_rest.app.utils.query_utils import to_dict from vector_rest.app.utils.query_utils import to_dict
from dataclasses import asdict from dataclasses import asdict

View File

@@ -19,7 +19,7 @@ from pydantic.main import BaseModel
from pydantic.networks import EmailStr, IPvAnyAddress from pydantic.networks import EmailStr, IPvAnyAddress
from typing import Optional from typing import Optional
from vactor_rest.app.common.consts import ( from vector_rest.app.common.consts import (
SW_TITLE, SW_TITLE,
SW_VERSION, SW_VERSION,
MAIL_REG_TITLE, MAIL_REG_TITLE,
@@ -29,7 +29,7 @@ from vactor_rest.app.common.consts import (
ADMIN_INIT_ACCOUNT_INFO, ADMIN_INIT_ACCOUNT_INFO,
DEFAULT_USER_ACCOUNT_PW DEFAULT_USER_ACCOUNT_PW
) )
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
class SWInfo(BaseModel): class SWInfo(BaseModel):
@@ -585,7 +585,7 @@ class VitModelType(str, Enum):
class VactorSearchReq(BaseModel): class VactorSearchReq(BaseModel):
""" """
### [Request] vactor 검색 ### [Request] vector 검색
""" """
query_image_path : str = Field(description='quary image', example='path') query_image_path : str = Field(description='quary image', example='path')
index_type : IndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) index_type : IndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2)
@@ -594,7 +594,7 @@ class VactorSearchReq(BaseModel):
class VactorSearchVitReportReq(BaseModel): class VactorSearchVitReportReq(BaseModel):
""" """
### [Request] vactor 검색(vit) 후 리포트 이미지 생성 ### [Request] vector 검색(vit) 후 리포트 이미지 생성
""" """
query_image_path : str = Field(description='quary image', example='path') query_image_path : str = Field(description='quary image', example='path')
index_type : VitIndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) index_type : VitIndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2)
@@ -604,7 +604,7 @@ class VactorSearchVitReportReq(BaseModel):
class VactorSearchVitReq(BaseModel): class VactorSearchVitReq(BaseModel):
""" """
### [Request] vactor 검색(vit) 후 이미지 생성 ### [Request] vector 검색(vit) 후 이미지 생성
""" """
query_image_path : str = Field(description='quary image', example='path') query_image_path : str = Field(description='quary image', example='path')
index_type : VitIndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) index_type : VitIndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2)

View File

@@ -17,13 +17,13 @@ import bcrypt
import jwt import jwt
from datetime import datetime, timedelta from datetime import datetime, timedelta
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app import models as M from vector_rest.app import models as M
from vactor_rest.app.database.conn import db from vector_rest.app.database.conn import db
from vactor_rest.app.common.config import conf from vector_rest.app.common.config import conf
from vactor_rest.app.database.schema import Users, UserLog from vector_rest.app.database.schema import Users, UserLog
from vactor_rest.app.utils.extra import query_to_groupby, AESCryptoCBC from vector_rest.app.utils.extra import query_to_groupby, AESCryptoCBC
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
router = APIRouter(prefix='/auth') router = APIRouter(prefix='/auth')

View File

@@ -15,12 +15,12 @@ from sqlalchemy.orm import Session
import bcrypt import bcrypt
from starlette.requests import Request from starlette.requests import Request
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app import models as M from vector_rest.app import models as M
from vactor_rest.app.database.conn import db, Base from vector_rest.app.database.conn import db, Base
from vactor_rest.app.database.schema import Users, UserLog from vector_rest.app.database.schema import Users, UserLog
from vactor_rest.app.utils.extra import FernetCrypto, AESCryptoCBC, AESCipher from vector_rest.app.utils.extra import FernetCrypto, AESCryptoCBC, AESCipher
from custom_logger.vactor_log import vactor_logger as LOG from custom_logger.vactor_log import vactor_logger as LOG

View File

@@ -11,8 +11,8 @@
from fastapi import APIRouter from fastapi import APIRouter
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
from vactor_rest.app.models import SWInfo from vector_rest.app.models import SWInfo
router = APIRouter() router = APIRouter()

View File

@@ -14,9 +14,9 @@ from fastapi import APIRouter, Depends, Body
from starlette.requests import Request from starlette.requests import Request
from typing import Annotated, List from typing import Annotated, List
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app import models as M from vector_rest.app import models as M
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
from custom_logger.vactor_log import vactor_logger as LOG from custom_logger.vactor_log import vactor_logger as LOG
from custom_apps.faiss_imagenet.main import search_idxs from custom_apps.faiss_imagenet.main import search_idxs
@@ -27,7 +27,7 @@ from custom_apps.FEATURE_VECTOR_SIMILARITY_FAISS.faiss_similarity_search import
router = APIRouter(prefix="/services") router = APIRouter(prefix="/services")
@router.post("/faiss/vactor/search/imagenet", summary="imagenet search", response_model=M.ResponseBase) @router.post("/faiss/vector/search/imagenet", summary="imagenet search", response_model=M.ResponseBase)
async def vactor_search(request: Request, request_body_info: M.VactorSearchReq): async def vactor_search(request: Request, request_body_info: M.VactorSearchReq):
""" """
## 벡터검색 ## 벡터검색
@@ -38,6 +38,7 @@ async def vactor_search(request: Request, request_body_info: M.VactorSearchReq):
""" """
response = M.ResponseBase() response = M.ResponseBase()
try: try:
LOG.info(request_body_info.query_image_path)
if os.path.exists(request_body_info.query_image_path): if os.path.exists(request_body_info.query_image_path):
search_idxs(image_path=request_body_info.query_image_path, search_idxs(image_path=request_body_info.query_image_path,
index_type=request_body_info.index_type, index_type=request_body_info.index_type,
@@ -52,7 +53,7 @@ async def vactor_search(request: Request, request_body_info: M.VactorSearchReq):
return response.set_error(e) return response.set_error(e)
@router.post("/faiss/vactor/search/vit/report", summary="vit search report", response_model=M.ResponseBase) @router.post("/faiss/vector/search/vit/report", summary="vit search report", response_model=M.ResponseBase)
async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchVitReportReq): async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchVitReportReq):
response = M.ResponseBase() response = M.ResponseBase()
try: try:
@@ -71,8 +72,8 @@ async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchV
return response.set_error(e) return response.set_error(e)
@router.post("/faiss/vactor/search/vit", summary="vit search", response_model=M.VactorSearchVitRes) @router.post("/faiss/vector/search/vit", summary="vit search", response_model=M.VactorSearchVitRes)
async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchVitReq): async def vactor_vit(request: Request, request_body_info: M.VactorSearchVitReq):
response = M.VactorSearchVitRes() response = M.VactorSearchVitRes()
try: try:
if not os.path.exists(request_body_info.query_image_path): if not os.path.exists(request_body_info.query_image_path):

View File

@@ -13,13 +13,13 @@ from fastapi import APIRouter
from starlette.requests import Request from starlette.requests import Request
import bcrypt import bcrypt
from vactor_rest.app.common import consts from vector_rest.app.common import consts
from vactor_rest.app import models as M from vector_rest.app import models as M
from vactor_rest.app.common.config import conf from vector_rest.app.common.config import conf
from vactor_rest.app.database.schema import Users from vector_rest.app.database.schema import Users
from vactor_rest.app.database.crud import table_select, table_update, table_delete from vector_rest.app.database.crud import table_select, table_update, table_delete
from vactor_rest.app.utils.extra import AESCryptoCBC from vector_rest.app.utils.extra import AESCryptoCBC
router = APIRouter(prefix='/user') router = APIRouter(prefix='/user')

View File

@@ -26,10 +26,10 @@ from itertools import groupby
from operator import attrgetter from operator import attrgetter
import uuid import uuid
from vactor_rest.app.common.consts import NUM_RETRY_UUID_GEN, SMTP_HOST, SMTP_PORT from vector_rest.app.common.consts import NUM_RETRY_UUID_GEN, SMTP_HOST, SMTP_PORT
from vactor_rest.app.utils.date_utils import D from vector_rest.app.utils.date_utils import D
from vactor_rest.app import models as M from vector_rest.app import models as M
from vactor_rest.app.common.consts import AES_CBC_PUBLIC_KEY, AES_CBC_IV, FERNET_SECRET_KEY from vector_rest.app.common.consts import AES_CBC_PUBLIC_KEY, AES_CBC_IV, FERNET_SECRET_KEY
async def send_mail(sender, sender_pw, title, recipient, contents_plain, contents_html, cc_list, smtp_host=SMTP_HOST, smtp_port=SMTP_PORT): async def send_mail(sender, sender_pw, title, recipient, contents_plain, contents_html, cc_list, smtp_host=SMTP_HOST, smtp_port=SMTP_PORT):