diff --git a/app/core/config.py b/app/core/config.py index 5e336f3..1bf7e00 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -5,14 +5,11 @@ load_dotenv() redis_url = os.getenv("REDIS_SERVER_URL") -bucket_name = os.getenv("BUCKET_NAME") -s3_region = os.getenv("S3_REGION") - +openai_key = os.getenv("OPENAI_API_KEY") class Settings(BaseSettings): REDIS_URL: str = redis_url - S3_REGION: str = bucket_name - BUCKET_NAME: str = s3_region + OPENAI_KEY: str = openai_key STREAM_JOB: str = "image.jobs" # SpringBoot에서 job 발행 (FastAPI에서 listen) STREAM_RESULT: str = "image.results" # FastAPI에서 결과 발행 (SpringBoot에서 listen) diff --git a/app/services/openai_service.py b/app/services/openai_service.py new file mode 100644 index 0000000..7455f19 --- /dev/null +++ b/app/services/openai_service.py @@ -0,0 +1,66 @@ +from app.core.config import settings +from openai import OpenAI +import json + +client = OpenAI(api_key=settings.OPENAI_KEY) + +class PregnancySafetyChecker: + def __init__(self, client: OpenAI): + self.client = client + + """ + - isSafe: 안전하면 1, 안전하지 않으면 0 + - description: 복용 가능 여부 설명 + """ + def ask_chatgpt_about_pregnancy_safety(self, pill_name: str) -> tuple[str, int]: + prompt = f""" + 약 이름: {pill_name} + 질문: 이 약은 임산부가 복용해도 안전한가요? 복용 가능 여부와 주의사항을 알려주세요. + description 안에는 문장마다 \\n 을 적용하세요. + 결과를 JSON 형식으로 정확히 반환하세요. 설명이나 다른 텍스트를 절대 덧붙이지 마세요. + 스키마: + {{ + "description": "복용 가능 여부 및 주의사항에 대한 설명", + "isSafe": 1 또는 0 + }} + """ + + response = self.client.chat.completions.create( + model="gpt-4o-mini", + messages=[{"role": "user", "content": prompt}], + temperature=0, + max_tokens=600, + response_format={"type": "json_object"} + ) + print("GPT Asking 성공...") + raw = response.choices[0].message.content.strip() + + try: + data = json.loads(raw) + except json.JSONDecodeError: + start = raw.find("{") + end = raw.rfind("}") + if start != -1 and end != -1 and start < end: + data = json.loads(raw[start:end+1]) + else: + # 디버깅 + preview = raw[:200].replace("\n", "\\n") + raise ValueError(f"응답이 유효한 JSON이 아닙니다. preview='{preview}'") + + description = data.get("description") + isSafe = data.get("isSafe") + + if isinstance(isSafe, bool): + isSafe = 1 if isSafe else 0 + elif isinstance(isSafe, str): + isSafe = 1 if isSafe.strip() in {"1", "true", "True"} else 0 + elif not isinstance(isSafe, int): + isSafe = 0 + + if not isinstance(description, str): + description = "" # 안전장치 + + return description, int(isSafe) + + +checker = PregnancySafetyChecker(client) \ No newline at end of file diff --git a/app/services/s3_service.py b/app/services/s3_service.py index 8cf7719..1e8debb 100644 --- a/app/services/s3_service.py +++ b/app/services/s3_service.py @@ -1,27 +1,15 @@ -import boto3 -from botocore.config import Config as BotoConfig import requests from io import BytesIO -from app.core.config import settings - class S3Service: def __init__(self): - self.client = boto3.client( - "s3", - region_name=settings.S3_REGION, - config=BotoConfig( - retries={"max_attempts": 5, "mode": "standard"}, - read_timeout=30, - connect_timeout=5, - ), - ) + pass def download_file_from_presigned_url(self, presigned_url: str) -> BytesIO: response = requests.get(presigned_url) response.raise_for_status() - - return BytesIO(response.content) # response 안의 content Stream으로 처리 + # response의 content를 BytesIO로 감싸 반환 + return BytesIO(response.content) s3_service = S3Service() diff --git a/app/worker/tasks.py b/app/worker/tasks.py index 3a22e33..63dfdc5 100644 --- a/app/worker/tasks.py +++ b/app/worker/tasks.py @@ -5,6 +5,7 @@ from app.core.config import settings from app.schemas.job import ImageJob, JobResult +from app.services.openai_service import checker from app.services.predictor_service import predictor_service from app.services.s3_service import s3_service @@ -27,11 +28,8 @@ async def process_image_scan(job: ImageJob, redis_client: redis.Redis): predictor_service.predict, stream_file ) - - # TODO: ChatGPT에 요청 결과 출력 - - isSafe = 0 - description = "일단은 테스트입니다. 추후에 GPT 부분 추가할 예정" + print(f"[task] Start Asking GPT for job_id={correlationId}") + description, isSafe = checker.ask_chatgpt_about_pregnancy_safety(pillName) finishedAt = datetime.utcnow().isoformat() result = JobResult( diff --git a/requirements.txt b/requirements.txt index 5cf02b2..d06a886 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,9 +3,9 @@ uvicorn redis pydantic pydantic-settings -boto3 requests torch==2.8.0 torchvision==0.23.0 Pillow==11.3.0 -dotenv \ No newline at end of file +dotenv +openai \ No newline at end of file