From 44bd86562d06a19c317888b7a4ae05dcb929f914 Mon Sep 17 00:00:00 2001 From: jwkim Date: Wed, 30 Jul 2025 13:29:24 +0900 Subject: [PATCH] =?UTF-8?q?edit=20:=20imagen=20->=20gemini=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD,=20bingimg=20->=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=EB=B6=88=EA=B0=80=20,=20=EB=B2=A1=ED=84=B0=EA=B2=80=EC=83=89ap?= =?UTF-8?q?i=20=EC=9D=B4=EB=AF=B8=EC=A7=80=EC=A0=80=EC=9E=A5=EC=9D=B4?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=ED=95=98=EB=8A=94=20=20api=20=EC=B6=94=EA=B0=80=20,?= =?UTF-8?q?=20vactor=20->=20vector=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + config.py | 28 +- .../faiss_functions.py | 2 +- custom_apps/bingart/bingart.py | 20 +- custom_apps/faiss_imagenet/main.py | 20 +- custom_apps/gemini/main.py | 40 ++ custom_apps/imagen/custom_imagen.py | 1 + custom_apps/utils.py | 2 +- custom_logger/vactor_log.py | 2 +- ...nment_vactor.yml => environment_vector.yml | 0 main_rest/app/main.py | 8 + main_rest/app/models.py | 53 ++- main_rest/app/routes/services.py | 346 ++++++++++++------ main_rest/app/utils/parsing_utils.py | 38 +- requirements_main.txt | 22 +- ...ents_vactor.txt => requirements_vector.txt | 0 rest_vactor.py | 6 - rest_vector.py | 6 + {vactor_rest => vector_rest}/.travis.yml | 0 .../app/api_request_sample.py | 0 .../app/common/config.py | 4 +- .../app/common/consts.py | 4 +- .../app/database/conn.py | 4 +- .../app/database/crud.py | 8 +- .../app/database/schema.py | 6 +- .../app/errors/exceptions.py | 2 +- {vactor_rest => vector_rest}/app/main.py | 12 +- .../app/middlewares/token_validator.py | 22 +- .../app/middlewares/trusted_hosts.py | 0 {vactor_rest => vector_rest}/app/models.py | 10 +- .../app/routes/auth.py | 14 +- .../app/routes/dev.py | 10 +- .../app/routes/index.py | 4 +- .../app/routes/services.py | 15 +- .../app/routes/users.py | 12 +- .../app/utils/date_utils.py | 0 .../app/utils/extra.py | 8 +- .../app/utils/logger.py | 0 .../app/utils/parsing_utils.py | 0 .../app/utils/query_utils.py | 0 {vactor_rest => vector_rest}/gunicorn.conf.py | 0 .../tests/__init__.py | 0 .../tests/conftest.py | 0 .../tests/test_auth.py | 0 .../tests/test_user.py | 0 45 files changed, 507 insertions(+), 223 deletions(-) create mode 100644 custom_apps/gemini/main.py rename environment_vactor.yml => environment_vector.yml (100%) rename requirements_vactor.txt => requirements_vector.txt (100%) delete mode 100644 rest_vactor.py create mode 100644 rest_vector.py rename {vactor_rest => vector_rest}/.travis.yml (100%) rename {vactor_rest => vector_rest}/app/api_request_sample.py (100%) rename {vactor_rest => vector_rest}/app/common/config.py (97%) rename {vactor_rest => vector_rest}/app/common/consts.py (97%) rename {vactor_rest => vector_rest}/app/database/conn.py (97%) rename {vactor_rest => vector_rest}/app/database/crud.py (97%) rename {vactor_rest => vector_rest}/app/database/schema.py (98%) rename {vactor_rest => vector_rest}/app/errors/exceptions.py (98%) rename {vactor_rest => vector_rest}/app/main.py (91%) rename {vactor_rest => vector_rest}/app/middlewares/token_validator.py (91%) rename {vactor_rest => vector_rest}/app/middlewares/trusted_hosts.py (100%) rename {vactor_rest => vector_rest}/app/models.py (99%) rename {vactor_rest => vector_rest}/app/routes/auth.py (87%) rename {vactor_rest => vector_rest}/app/routes/dev.py (92%) rename {vactor_rest => vector_rest}/app/routes/index.py (86%) rename {vactor_rest => vector_rest}/app/routes/services.py (87%) rename {vactor_rest => vector_rest}/app/routes/users.py (97%) rename {vactor_rest => vector_rest}/app/utils/date_utils.py (100%) rename {vactor_rest => vector_rest}/app/utils/extra.py (96%) rename {vactor_rest => vector_rest}/app/utils/logger.py (100%) rename {vactor_rest => vector_rest}/app/utils/parsing_utils.py (100%) rename {vactor_rest => vector_rest}/app/utils/query_utils.py (100%) rename {vactor_rest => vector_rest}/gunicorn.conf.py (100%) rename {vactor_rest => vector_rest}/tests/__init__.py (100%) rename {vactor_rest => vector_rest}/tests/conftest.py (100%) rename {vactor_rest => vector_rest}/tests/test_auth.py (100%) rename {vactor_rest => vector_rest}/tests/test_user.py (100%) diff --git a/README.md b/README.md index ee62f85..263a9e6 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ RESTful API Server ``` gcloud init 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 diff --git a/config.py b/config.py index c09375e..63503a5 100644 --- a/config.py +++ b/config.py @@ -1,8 +1,12 @@ class Config: 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.remote_folder = "/home/fermat/STORAGE/01.Projects/A2TEC/K_EYEWEAR/02.ML_DATA/Image_generator_result" self.sftp_host = "192.168.200.230" @@ -11,6 +15,9 @@ class Config: self.sftp_pw = "1234" def set_dev(self): + """ + 개발용 + """ self.config = 'dev' self.remote_folder = "/home/fermat/project/FM_TEST_REST_SERVER/result" self.sftp_host = "192.168.200.231" @@ -21,7 +28,22 @@ class Config: import os if not os.path.exists(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.set_dev() \ No newline at end of file +rest_config.set_dev() +rest_config.toggle_imagen() \ No newline at end of file diff --git a/custom_apps/FEATURE_VECTOR_SIMILARITY_FAISS/faiss_functions.py b/custom_apps/FEATURE_VECTOR_SIMILARITY_FAISS/faiss_functions.py index 5702ecd..b07c8b0 100755 --- a/custom_apps/FEATURE_VECTOR_SIMILARITY_FAISS/faiss_functions.py +++ b/custom_apps/FEATURE_VECTOR_SIMILARITY_FAISS/faiss_functions.py @@ -56,7 +56,7 @@ Implementation """ 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 diff --git a/custom_apps/bingart/bingart.py b/custom_apps/bingart/bingart.py index 7200b55..7a76889 100644 --- a/custom_apps/bingart/bingart.py +++ b/custom_apps/bingart/bingart.py @@ -57,9 +57,9 @@ class BingArtGenerator: else: return None - def link_to_img(self, img_links:list): + def link_to_img_remote(self, img_links:list): """ - 이미지 링크로 이미지 파일 저장 + 이미지 링크로 이미지 파일 원격지에 저장 """ jpeg_index = 1 @@ -80,6 +80,20 @@ class BingArtGenerator: return 0 else: - self.link_to_img(img_links=image_links) + self.link_to_img_remote(img_links=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 diff --git a/custom_apps/faiss_imagenet/main.py b/custom_apps/faiss_imagenet/main.py index 9670871..1d5d12d 100644 --- a/custom_apps/faiss_imagenet/main.py +++ b/custom_apps/faiss_imagenet/main.py @@ -1,5 +1,7 @@ import os 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.const import * @@ -15,17 +17,29 @@ def search_idxs(image_path,dataset_bin=DATASET_BIN,index_type="hnsw",search_num= DIM = 1280 + # res = faiss.StandardGpuResources() + # __res = faiss.StandardGpuResources() + + dataset_fvces, dataset_index = preprocessing(DIM,dataset_bin,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) - - # print(dists[0]) - # print(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): directory_path, file = os.path.split(query_image_path) _name, extension = os.path.splitext(file) diff --git a/custom_apps/gemini/main.py b/custom_apps/gemini/main.py new file mode 100644 index 0000000..1f26df1 --- /dev/null +++ b/custom_apps/gemini/main.py @@ -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 \ No newline at end of file diff --git a/custom_apps/imagen/custom_imagen.py b/custom_apps/imagen/custom_imagen.py index 973e49b..59f225d 100644 --- a/custom_apps/imagen/custom_imagen.py +++ b/custom_apps/imagen/custom_imagen.py @@ -15,6 +15,7 @@ class ImagenConst: project_id = "glasses-imagen" location = "asia-east1" model = "imagen-3.0-generate-001" + # model = "imagen-3.0-fast-generate-001" def imagen_generate_image(prompt,download_count=1): diff --git a/custom_apps/utils.py b/custom_apps/utils.py index 18afe0d..8636fa1 100644 --- a/custom_apps/utils.py +++ b/custom_apps/utils.py @@ -1,6 +1,6 @@ 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): self.cookie = self.DEFAULT_COOKIE diff --git a/custom_logger/vactor_log.py b/custom_logger/vactor_log.py index 5b65d18..fa20da7 100644 --- a/custom_logger/vactor_log.py +++ b/custom_logger/vactor_log.py @@ -8,7 +8,7 @@ vactor_logger = None _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_LEVEL = logging.INFO diff --git a/environment_vactor.yml b/environment_vector.yml similarity index 100% rename from environment_vactor.yml rename to environment_vector.yml diff --git a/main_rest/app/main.py b/main_rest/app/main.py index d5e598f..4297637 100644 --- a/main_rest/app/main.py +++ b/main_rest/app/main.py @@ -40,6 +40,14 @@ async def lifespan(app: FastAPI): # When service starts. 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 # When service is stopped. diff --git a/main_rest/app/models.py b/main_rest/app/models.py index 6e027c3..ce1e4d0 100644 --- a/main_rest/app/models.py +++ b/main_rest/app/models.py @@ -600,31 +600,40 @@ class BingCookieSetReq(BaseModel): class VactorImageSearchReq(BaseModel): """ - ### [Request] vactor image search request + ### [Request] vector image search request """ prompt : str = Field(description='프롬프트', example='검은색 안경') indexType : str = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) 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='검은색 안경') modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14) indexType : str = Field(VitIndexType.l2, description='인덱스 타입', example=VitIndexType.l2) 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='검은색 안경') modelType : str = Field(VitModelType.l14, description='pretrained model 타입', example=VitModelType.l14) 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='') #=============================================================================== #=============================================================================== @@ -672,4 +681,30 @@ class BingCookieSetRes(ResponseBase): BingCookieSetRes.result = True BingCookieSetRes.error = None BingCookieSetRes.currentCookie = current_cookie - return BingCookieSetRes \ No newline at end of file + 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 \ No newline at end of file diff --git a/main_rest/app/routes/services.py b/main_rest/app/routes/services.py index aca819f..fcde088 100644 --- a/main_rest/app/routes/services.py +++ b/main_rest/app/routes/services.py @@ -9,7 +9,7 @@ @brief: services api """ -import requests, json, traceback, os +import requests, json, traceback, os, shutil from fastapi import APIRouter, Depends, Body from starlette.requests import Request 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 import models as M 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_apps.bingimagecreator.utils import DallEArgument,dalle3_generate_image 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 main_rest.app.utils.parsing_utils import download_range 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 config import rest_config +from const import TEMP_FOLDER router = APIRouter(prefix="/services") -@router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes) -async def bing_cookie_set(request: Request, request_body_info: M.BingCookieSetReq): - """ - ## Bing cookie set - > 쿠키정보 set +# @router.post("/bing/cookie/set", summary="bing 관련 쿠키 set", response_model=M.BingCookieSetRes) +# async def bing_cookie_set(request: Request, request_body_info: M.BingCookieSetReq): +# """ +# ## Bing cookie set +# > 쿠키정보 set - ## 정보 - > cookie 값이 빈 값일경우 쿠키정보를 set 하지 않고 현재 쿠키값 return 함 - > cookie 값이 정상 쿠키 인지는 확인안함 +# ## 정보 +# > cookie 값이 빈 값일경우 쿠키정보를 set 하지 않고 현재 쿠키값 return 함 +# > cookie 값이 정상 쿠키 인지는 확인안함 - """ - response = M.BingCookieSetRes() - try: - if len(request_body_info.cookie) == 0: - pass - else: - cookie_manager.set_cookie(request_body_info.cookie) +# """ +# response = M.BingCookieSetRes() +# try: +# if len(request_body_info.cookie) == 0: +# pass +# else: +# 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: - LOG.error(traceback.format_exc()) - return response.set_error(e,current_cookie=cookie_manager.get_cookie()) +# except Exception as e: +# LOG.error(traceback.format_exc()) +# 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) -async def bing_img_generate(request: Request, request_body_info: M.ImageGenerateReq): - """ - ## 이미지 생성(AI) - bing image generator (DALL-E 3) - > bing image generator를 이용하여 이미지 생성 +# @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): +# """ +# ## 이미지 생성(AI) - bing image generator (DALL-E 3) +# > bing image generator를 이용하여 이미지 생성 - ### Requriements +# ### Requriements - ## 정보 - > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함 - > *동작 안함. +# ## 정보 +# > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함 - """ - response = M.ImageGenerateRes() - try: - if not download_range(request_body_info.downloadCount): - raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})") +# """ +# response = M.ImageGenerateRes() +# try: +# if not download_range(request_body_info.downloadCount): +# raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})") - args = DallEArgument( - prompt=request_body_info.prompt, - download_count=request_body_info.downloadCount - ) +# args = DallEArgument( +# prompt=request_body_info.prompt, +# download_count=request_body_info.downloadCount +# ) - info = dalle3_generate_image(args) +# info = dalle3_generate_image(args) - if info.get_error_messages(): - error_message = f"파일생성 error: {info.get_error_messages()}" - LOG.error(error_message) - return response.set_error(error=error_message, img_len=info.get_counter()) +# if info.get_error_messages(): +# error_message = f"파일생성 error: {info.get_error_messages()}" +# LOG.error(error_message) +# 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: - LOG.error(traceback.format_exc()) - return response.set_error(e) +# except Exception as e: +# LOG.error(traceback.format_exc()) +# return response.set_error(e) -@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): - """ - ## 이미지 생성(AI) - bing art (DALL-E 3) - > bing art를 이용하여 이미지 생성 +# @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): +# """ +# ## 이미지 생성(AI) - bing art (DALL-E 3) +# > bing art를 이용하여 이미지 생성 - ### Requriements +# ### Requriements - ## 정보 - > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함 - > *동작 안함. +# ## 정보 +# > 오류 발생시 오류 발생한 파일은 에러 메세지에만 남기고 저장은 안함 +# > *동작 안함. - """ - response = M.ImageGenerateRes() - try: - if not download_range(request_body_info.downloadCount): - raise Exception(f"downloadCount is 1~4 (current value = {request_body_info.downloadCount})") +# """ +# response = M.ImageGenerateRes() +# try: +# if not download_range(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: - LOG.error(traceback.format_exc()) - return response.set_error(e) +# except Exception as e: +# LOG.error(traceback.format_exc()) +# return response.set_error(e) @router.post("/imageGenerate/imagen", summary="이미지 생성(AI) - imagen", response_model=M.ImageGenerateRes) 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 > imagen AI를 이용하여 이미지 생성 - ### Requriements - > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) - > - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함. """ + # imagen 사용중단 gemini로 변경 + response = M.ImageGenerateRes() try: if not download_range(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, - download_count=request_body_info.downloadCount - ) + # NOTE(JWKIM) : imagen 사용 중단 + # 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") + + # 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")) - return response.set_message(img_len=img_length) + # 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: 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/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase) -async def vactor_imagenet(request: Request, request_body_info: M.VactorImageSearchReq): - """ - ## 벡터 이미지 검색 - imagen - > imagen AI를 이용하여 이미지 생성 후 vactor 검색 +# @router.post("/vactorImageSearch/imagenet/imageGenerate/imagen", summary="벡터 이미지 검색(imagenet) - imagen", response_model=M.ResponseBase) +# async def vactor_imagenet(request: Request, request_body_info: M.VactorImageSearchReq): +# """ +# ## 벡터 이미지 검색 - imagen +# > imagen AI를 이용하여 이미지 생성 후 vector 검색 - ### Requriements - > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) - > - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함. +# ### Requriements +# > - googlecli 설치(https://cloud.google.com/sdk/docs/install?hl=ko#linux) +# > - const.py 에 지정한 OUTPUT_FOLDER 하위에 imagen 폴더가 있어야함. - """ - response = M.ResponseBase() - try: - 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})") +# """ +# # NOTE(JWKIM) : GPU 메모리 이슈로 사용 중단 +# response = M.ResponseBase() +# try: +# 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, - 'index_type' : request_body_info.indexType, - '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)) +# # img_path = imagen_generate_image_path(image_prompt=request_body_info.prompt) #imagen +# img_path = gemini_image(request_body_info.prompt, os.path.join(TEMP_FOLDER, _temp_folder)) #gemini - if vactor_response.status_code != 200: - raise Exception(f"response error: {json.loads(vactor_response.text)['error']}") +# vector_request_data = {'query_image_path' : img_path, +# '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: - raise Exception(f"vactor error: {json.loads(vactor_response.text)['error']}") +# if vector_response.status_code != 200: +# raise Exception(f"response error: {json.loads(vector_response.text)['error']}") - # remote - _directory_path, _file = os.path.split(img_path) - _base_bame = os.path.basename(_directory_path) +# if json.loads(vector_response.text)["error"] != None: +# raise Exception(f"vector error: {json.loads(vector_response.text)['error']}") - # remote 폴더 생성 - sftp_client.remote_mkdir(os.path.join(rest_config.remote_folder, _base_bame)) +# # remote +# _directory_path, _file = os.path.split(img_path) - # 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, _base_bame, i)) +# # remote 폴더 생성 +# sftp_client.remote_mkdir(os.path.join(rest_config.remote_folder, _temp_folder)) - 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: - LOG.error(traceback.format_exc()) - return response.set_error(error=e) +# except Exception as e: +# LOG.error(traceback.format_exc()) +# return response.set_error(error=e) @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 - > imagen AI를 이용하여 이미지 생성 후 vactor 검색 그후 결과 이미지 생성 + > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 결과 이미지 생성 ### Requriements > - 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]: 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, '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/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) @@ -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']}") 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_percents = vector_response_dict.get('img_list').get('result_percents') @@ -267,12 +294,92 @@ async def vactor_vit_report(request: Request, request_body_info: M.VactorImageSe del query_image_path 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) -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 생성 - > imagen AI를 이용하여 이미지 생성 후 vactor 검색 그후 종합결과 이미지 생성 + > imagen AI를 이용하여 이미지 생성 후 vector 검색 그후 종합결과 이미지 생성 ### Requriements > - 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]: 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" 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, '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: raise Exception(f"response error: {json.loads(vactor_response.text)['error']}") 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 폴더에 이미지 저장 sftp_client.remote_copy_data(local_path=report_image_path, diff --git a/main_rest/app/utils/parsing_utils.py b/main_rest/app/utils/parsing_utils.py index 946dfbc..0c4ccf0 100644 --- a/main_rest/app/utils/parsing_utils.py +++ b/main_rest/app/utils/parsing_utils.py @@ -1,5 +1,9 @@ +import os +import base64 + from const import ILLEGAL_FILE_NAME + def prompt_to_filenames(prompt): """ prompt 에 사용할 수 없는 문자가 있으면 '_' 로 치환 @@ -22,4 +26,36 @@ def download_range(download_count:int,max=4): return True return False - \ No newline at end of file + + +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}") \ No newline at end of file diff --git a/requirements_main.txt b/requirements_main.txt index 13bc4d5..95d4e34 100644 --- a/requirements_main.txt +++ b/requirements_main.txt @@ -15,21 +15,25 @@ email-validator requests #imagen -google-cloud-aiplatform -Pillow +# google-cloud-aiplatform +# Pillow # #bing img -aiohttp -regex -requests -httpx -nest_asyncio +# aiohttp +# regex +# requests +# httpx +# nest_asyncio -# #bing art -bingart==1.1.0 +# # #bing art +# bingart==1.1.0 #DALL-E 3 # openai +# gemini +google-genai +pillow + # SFTP paramiko \ No newline at end of file diff --git a/requirements_vactor.txt b/requirements_vector.txt similarity index 100% rename from requirements_vactor.txt rename to requirements_vector.txt diff --git a/rest_vactor.py b/rest_vactor.py deleted file mode 100644 index 9df1583..0000000 --- a/rest_vactor.py +++ /dev/null @@ -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) \ No newline at end of file diff --git a/rest_vector.py b/rest_vector.py new file mode 100644 index 0000000..c854165 --- /dev/null +++ b/rest_vector.py @@ -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) \ No newline at end of file diff --git a/vactor_rest/.travis.yml b/vector_rest/.travis.yml similarity index 100% rename from vactor_rest/.travis.yml rename to vector_rest/.travis.yml diff --git a/vactor_rest/app/api_request_sample.py b/vector_rest/app/api_request_sample.py similarity index 100% rename from vactor_rest/app/api_request_sample.py rename to vector_rest/app/api_request_sample.py diff --git a/vactor_rest/app/common/config.py b/vector_rest/app/common/config.py similarity index 97% rename from vactor_rest/app/common/config.py rename to vector_rest/app/common/config.py index 4513ccb..d1da9fd 100644 --- a/vactor_rest/app/common/config.py +++ b/vector_rest/app/common/config.py @@ -12,8 +12,8 @@ from dataclasses import dataclass from os import path, environ -from vactor_rest.app.common import consts -from vactor_rest.app.models import UserInfo +from vector_rest.app.common import consts +from vector_rest.app.models import UserInfo base_dir = path.dirname(path.dirname(path.dirname(path.abspath(__file__)))) diff --git a/vactor_rest/app/common/consts.py b/vector_rest/app/common/consts.py similarity index 97% rename from vactor_rest/app/common/consts.py rename to vector_rest/app/common/consts.py index db15083..603dcc1 100644 --- a/vactor_rest/app/common/consts.py +++ b/vector_rest/app/common/consts.py @@ -12,11 +12,11 @@ # SUPPORT PROJECT 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_VERSION = '0.1.0' SW_DESCRIPTION = f''' -### FERMAT-TEST(Vactor REST API) REST API +### FERMAT-TEST(Vector REST API) REST API ## API 이용법 - 개별 API 설명과 Request/Response schema 참조 diff --git a/vactor_rest/app/database/conn.py b/vector_rest/app/database/conn.py similarity index 97% rename from vactor_rest/app/database/conn.py rename to vector_rest/app/database/conn.py index 45e6d12..4290518 100644 --- a/vactor_rest/app/database/conn.py +++ b/vector_rest/app/database/conn.py @@ -126,8 +126,8 @@ Base = declarative_base() # NOTE(hsj100): ADMINISTRATOR def create_admin(db_session): import bcrypt - from vactor_rest.app.database.schema import Users - from vactor_rest.app.common.consts import ADMIN_INIT_ACCOUNT_INFO + from vector_rest.app.database.schema import Users + from vector_rest.app.common.consts import ADMIN_INIT_ACCOUNT_INFO session = db_session() diff --git a/vactor_rest/app/database/crud.py b/vector_rest/app/database/crud.py similarity index 97% rename from vactor_rest/app/database/crud.py rename to vector_rest/app/database/crud.py index 286058d..ee99b6a 100644 --- a/vactor_rest/app/database/crud.py +++ b/vector_rest/app/database/crud.py @@ -16,10 +16,10 @@ from sqlalchemy import func, desc from fastapi import APIRouter, Depends, Body from sqlalchemy.orm import Session -from vactor_rest.app import models as M -from vactor_rest.app.database.conn import Base, db -from vactor_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 import models as M +from vector_rest.app.database.conn import Base, db +from vector_rest.app.database.schema import Users, UserLog +from vector_rest.app.utils.extra import query_to_groupby, query_to_groupby_date def get_month_info_list(start: datetime, end: datetime): diff --git a/vactor_rest/app/database/schema.py b/vector_rest/app/database/schema.py similarity index 98% rename from vactor_rest/app/database/schema.py rename to vector_rest/app/database/schema.py index 9dcfb71..3bf67d4 100644 --- a/vactor_rest/app/database/schema.py +++ b/vector_rest/app/database/schema.py @@ -21,9 +21,9 @@ from sqlalchemy import ( ) from sqlalchemy.orm import Session, relationship -from vactor_rest.app.database.conn import Base, db -from vactor_rest.app.utils.date_utils import D -from vactor_rest.app.models import ( +from vector_rest.app.database.conn import Base, db +from vector_rest.app.utils.date_utils import D +from vector_rest.app.models import ( SexType, UserType, MemberType, diff --git a/vactor_rest/app/errors/exceptions.py b/vector_rest/app/errors/exceptions.py similarity index 98% rename from vactor_rest/app/errors/exceptions.py rename to vector_rest/app/errors/exceptions.py index 3980eb5..9247a36 100644 --- a/vactor_rest/app/errors/exceptions.py +++ b/vector_rest/app/errors/exceptions.py @@ -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: diff --git a/vactor_rest/app/main.py b/vector_rest/app/main.py similarity index 91% rename from vactor_rest/app/main.py rename to vector_rest/app/main.py index c6018a2..bca2277 100644 --- a/vactor_rest/app/main.py +++ b/vector_rest/app/main.py @@ -20,13 +20,13 @@ from fastapi.responses import JSONResponse from starlette.middleware.base import BaseHTTPMiddleware 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 vactor_rest.app.common.config import conf -from vactor_rest.app.middlewares.token_validator import access_control -from vactor_rest.app.middlewares.trusted_hosts import TrustedHostMiddleware -from vactor_rest.app.routes import dev, index, auth, users, services +from vector_rest.app.database.conn import db +from vector_rest.app.common.config import conf +from vector_rest.app.middlewares.token_validator import access_control +from vector_rest.app.middlewares.trusted_hosts import TrustedHostMiddleware +from vector_rest.app.routes import dev, index, auth, users, services from contextlib import asynccontextmanager from custom_logger.vactor_log import vactor_logger as LOG diff --git a/vactor_rest/app/middlewares/token_validator.py b/vector_rest/app/middlewares/token_validator.py similarity index 91% rename from vactor_rest/app/middlewares/token_validator.py rename to vector_rest/app/middlewares/token_validator.py index bdba04f..6d7cd33 100644 --- a/vactor_rest/app/middlewares/token_validator.py +++ b/vector_rest/app/middlewares/token_validator.py @@ -12,19 +12,19 @@ from jwt.exceptions import ExpiredSignatureError, DecodeError from starlette.requests import Request from starlette.responses import JSONResponse -from vactor_rest.app.common.consts import EXCEPT_PATH_LIST, EXCEPT_PATH_REGEX -from vactor_rest.app.database.conn import db -from vactor_rest.app.database.schema import Users, ApiKeys -from vactor_rest.app.errors import exceptions as ex +from vector_rest.app.common.consts import EXCEPT_PATH_LIST, EXCEPT_PATH_REGEX +from vector_rest.app.database.conn import db +from vector_rest.app.database.schema import Users, ApiKeys +from vector_rest.app.errors import exceptions as ex -from vactor_rest.app.common import consts -from vactor_rest.app.common.config import conf -from vactor_rest.app.errors.exceptions import APIException, SqlFailureEx, APIQueryStringEx -from vactor_rest.app.models import UserToken +from vector_rest.app.common import consts +from vector_rest.app.common.config import conf +from vector_rest.app.errors.exceptions import APIException, SqlFailureEx, APIQueryStringEx +from vector_rest.app.models import UserToken -from vactor_rest.app.utils.date_utils import D -from vactor_rest.app.utils.logger import api_logger -from vactor_rest.app.utils.query_utils import to_dict +from vector_rest.app.utils.date_utils import D +from vector_rest.app.utils.logger import api_logger +from vector_rest.app.utils.query_utils import to_dict from dataclasses import asdict diff --git a/vactor_rest/app/middlewares/trusted_hosts.py b/vector_rest/app/middlewares/trusted_hosts.py similarity index 100% rename from vactor_rest/app/middlewares/trusted_hosts.py rename to vector_rest/app/middlewares/trusted_hosts.py diff --git a/vactor_rest/app/models.py b/vector_rest/app/models.py similarity index 99% rename from vactor_rest/app/models.py rename to vector_rest/app/models.py index d7d7414..3b4efcf 100644 --- a/vactor_rest/app/models.py +++ b/vector_rest/app/models.py @@ -19,7 +19,7 @@ from pydantic.main import BaseModel from pydantic.networks import EmailStr, IPvAnyAddress from typing import Optional -from vactor_rest.app.common.consts import ( +from vector_rest.app.common.consts import ( SW_TITLE, SW_VERSION, MAIL_REG_TITLE, @@ -29,7 +29,7 @@ from vactor_rest.app.common.consts import ( ADMIN_INIT_ACCOUNT_INFO, 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): @@ -585,7 +585,7 @@ class VitModelType(str, Enum): class VactorSearchReq(BaseModel): """ - ### [Request] vactor 검색 + ### [Request] vector 검색 """ query_image_path : str = Field(description='quary image', example='path') index_type : IndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) @@ -594,7 +594,7 @@ class VactorSearchReq(BaseModel): class VactorSearchVitReportReq(BaseModel): """ - ### [Request] vactor 검색(vit) 후 리포트 이미지 생성 + ### [Request] vector 검색(vit) 후 리포트 이미지 생성 """ query_image_path : str = Field(description='quary image', example='path') index_type : VitIndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) @@ -604,7 +604,7 @@ class VactorSearchVitReportReq(BaseModel): class VactorSearchVitReq(BaseModel): """ - ### [Request] vactor 검색(vit) 후 이미지 생성 + ### [Request] vector 검색(vit) 후 이미지 생성 """ query_image_path : str = Field(description='quary image', example='path') index_type : VitIndexType = Field(IndexType.l2, description='인덱스 타입', example=IndexType.l2) diff --git a/vactor_rest/app/routes/auth.py b/vector_rest/app/routes/auth.py similarity index 87% rename from vactor_rest/app/routes/auth.py rename to vector_rest/app/routes/auth.py index 1a98b19..4d9825e 100644 --- a/vactor_rest/app/routes/auth.py +++ b/vector_rest/app/routes/auth.py @@ -17,13 +17,13 @@ import bcrypt import jwt from datetime import datetime, timedelta -from vactor_rest.app.common import consts -from vactor_rest.app import models as M -from vactor_rest.app.database.conn import db -from vactor_rest.app.common.config import conf -from vactor_rest.app.database.schema import Users, UserLog -from vactor_rest.app.utils.extra import query_to_groupby, AESCryptoCBC -from vactor_rest.app.utils.date_utils import D +from vector_rest.app.common import consts +from vector_rest.app import models as M +from vector_rest.app.database.conn import db +from vector_rest.app.common.config import conf +from vector_rest.app.database.schema import Users, UserLog +from vector_rest.app.utils.extra import query_to_groupby, AESCryptoCBC +from vector_rest.app.utils.date_utils import D router = APIRouter(prefix='/auth') diff --git a/vactor_rest/app/routes/dev.py b/vector_rest/app/routes/dev.py similarity index 92% rename from vactor_rest/app/routes/dev.py rename to vector_rest/app/routes/dev.py index 315a341..4669d94 100644 --- a/vactor_rest/app/routes/dev.py +++ b/vector_rest/app/routes/dev.py @@ -15,12 +15,12 @@ from sqlalchemy.orm import Session import bcrypt from starlette.requests import Request -from vactor_rest.app.common import consts -from vactor_rest.app import models as M -from vactor_rest.app.database.conn import db, Base -from vactor_rest.app.database.schema import Users, UserLog +from vector_rest.app.common import consts +from vector_rest.app import models as M +from vector_rest.app.database.conn import db, Base +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 diff --git a/vactor_rest/app/routes/index.py b/vector_rest/app/routes/index.py similarity index 86% rename from vactor_rest/app/routes/index.py rename to vector_rest/app/routes/index.py index 3e5d198..762f6bf 100644 --- a/vactor_rest/app/routes/index.py +++ b/vector_rest/app/routes/index.py @@ -11,8 +11,8 @@ from fastapi import APIRouter -from vactor_rest.app.utils.date_utils import D -from vactor_rest.app.models import SWInfo +from vector_rest.app.utils.date_utils import D +from vector_rest.app.models import SWInfo router = APIRouter() diff --git a/vactor_rest/app/routes/services.py b/vector_rest/app/routes/services.py similarity index 87% rename from vactor_rest/app/routes/services.py rename to vector_rest/app/routes/services.py index 4453100..19eb48f 100644 --- a/vactor_rest/app/routes/services.py +++ b/vector_rest/app/routes/services.py @@ -14,9 +14,9 @@ from fastapi import APIRouter, Depends, Body from starlette.requests import Request from typing import Annotated, List -from vactor_rest.app.common import consts -from vactor_rest.app import models as M -from vactor_rest.app.utils.date_utils import D +from vector_rest.app.common import consts +from vector_rest.app import models as M +from vector_rest.app.utils.date_utils import D from custom_logger.vactor_log import vactor_logger as LOG 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.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): """ ## 벡터검색 @@ -38,6 +38,7 @@ async def vactor_search(request: Request, request_body_info: M.VactorSearchReq): """ response = M.ResponseBase() try: + LOG.info(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, 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) -@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): response = M.ResponseBase() try: @@ -71,8 +72,8 @@ async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchV return response.set_error(e) -@router.post("/faiss/vactor/search/vit", summary="vit search", response_model=M.VactorSearchVitRes) -async def vactor_report_vit(request: Request, request_body_info: M.VactorSearchVitReq): +@router.post("/faiss/vector/search/vit", summary="vit search", response_model=M.VactorSearchVitRes) +async def vactor_vit(request: Request, request_body_info: M.VactorSearchVitReq): response = M.VactorSearchVitRes() try: if not os.path.exists(request_body_info.query_image_path): diff --git a/vactor_rest/app/routes/users.py b/vector_rest/app/routes/users.py similarity index 97% rename from vactor_rest/app/routes/users.py rename to vector_rest/app/routes/users.py index 357023d..7b1f497 100644 --- a/vactor_rest/app/routes/users.py +++ b/vector_rest/app/routes/users.py @@ -13,13 +13,13 @@ from fastapi import APIRouter from starlette.requests import Request import bcrypt -from vactor_rest.app.common import consts -from vactor_rest.app import models as M -from vactor_rest.app.common.config import conf -from vactor_rest.app.database.schema import Users -from vactor_rest.app.database.crud import table_select, table_update, table_delete +from vector_rest.app.common import consts +from vector_rest.app import models as M +from vector_rest.app.common.config import conf +from vector_rest.app.database.schema import Users +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') diff --git a/vactor_rest/app/utils/date_utils.py b/vector_rest/app/utils/date_utils.py similarity index 100% rename from vactor_rest/app/utils/date_utils.py rename to vector_rest/app/utils/date_utils.py diff --git a/vactor_rest/app/utils/extra.py b/vector_rest/app/utils/extra.py similarity index 96% rename from vactor_rest/app/utils/extra.py rename to vector_rest/app/utils/extra.py index 8f7da52..df28d38 100644 --- a/vactor_rest/app/utils/extra.py +++ b/vector_rest/app/utils/extra.py @@ -26,10 +26,10 @@ from itertools import groupby from operator import attrgetter import uuid -from vactor_rest.app.common.consts import NUM_RETRY_UUID_GEN, SMTP_HOST, SMTP_PORT -from vactor_rest.app.utils.date_utils import D -from vactor_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 NUM_RETRY_UUID_GEN, SMTP_HOST, SMTP_PORT +from vector_rest.app.utils.date_utils import D +from vector_rest.app import models as M +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): diff --git a/vactor_rest/app/utils/logger.py b/vector_rest/app/utils/logger.py similarity index 100% rename from vactor_rest/app/utils/logger.py rename to vector_rest/app/utils/logger.py diff --git a/vactor_rest/app/utils/parsing_utils.py b/vector_rest/app/utils/parsing_utils.py similarity index 100% rename from vactor_rest/app/utils/parsing_utils.py rename to vector_rest/app/utils/parsing_utils.py diff --git a/vactor_rest/app/utils/query_utils.py b/vector_rest/app/utils/query_utils.py similarity index 100% rename from vactor_rest/app/utils/query_utils.py rename to vector_rest/app/utils/query_utils.py diff --git a/vactor_rest/gunicorn.conf.py b/vector_rest/gunicorn.conf.py similarity index 100% rename from vactor_rest/gunicorn.conf.py rename to vector_rest/gunicorn.conf.py diff --git a/vactor_rest/tests/__init__.py b/vector_rest/tests/__init__.py similarity index 100% rename from vactor_rest/tests/__init__.py rename to vector_rest/tests/__init__.py diff --git a/vactor_rest/tests/conftest.py b/vector_rest/tests/conftest.py similarity index 100% rename from vactor_rest/tests/conftest.py rename to vector_rest/tests/conftest.py diff --git a/vactor_rest/tests/test_auth.py b/vector_rest/tests/test_auth.py similarity index 100% rename from vactor_rest/tests/test_auth.py rename to vector_rest/tests/test_auth.py diff --git a/vactor_rest/tests/test_user.py b/vector_rest/tests/test_user.py similarity index 100% rename from vactor_rest/tests/test_user.py rename to vector_rest/tests/test_user.py