해결된 질문
작성
·
413
·
수정됨
0
안녕하세요 진석님! 현재 강의를 들은 다음 웹페이지를 만들고 있는데 사진과 함께 포스팅을 하면 사진에 있는 글자를 인식하여 번역하고 따로 필드에 저장하는 것을 구현하고 있습니다.(google cloud visionAI, translationAPI 이용)
현재 celery을 사용하는 방법은 따로 찾아봐서 잘 알게되엇는데(https://realpython.com/asynchronous-tasks-with-django-and-celery/)
#views.py
from .tasks import process_image_ocr_and_translation
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [AllowAny]
def perform_create(self, serializer):
post = serializer.save(author=self.request.user)
tag_list = post.extract_tag_list()
post.tag_set.add(*tag_list)
process_image_ocr_and_translation.delay(post.id)
# tasks.py
from celery import shared_task
from .models import Post
from module.API import detect_text, translate_text
@shared_task
def process_image_ocr_and_translation(post_id):
post = Post.objects.get(pk=post_id)
post.photo.file.open()
image_path = post.photo.path
detected_text = detect_text(image_path)
translated_text = translate_text(detected_text)
post.ocr_text = translated_text
post.save()
#celery.py
import os
from celery import Celery
# Set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "backend.settings.dev")
app = Celery("backend")
# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object("django.conf:settings", namespace="CELERY")
# Load task modules from all registered Django apps.
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print(f"Request: {self.request!r}")
#common.py
# Celery settings
# 베포를 할때는 이부분이 변경이 되어야 한다?
CELERY_BROKER_URL = "redis://localhost:6379"
#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
# CELERY_ACCEPT_CONTENT = ["application/json"]
CELERY_RESULT_BACKEND = "redis://localhost:6379"
# CELERY_TASK_SERIALIZER = "json"
#module.API
from google.cloud import vision
import io
from google.cloud import translate
def detect_text(path):
"""Detects text in the file."""
client = vision.ImageAnnotatorClient()
with io.open(path, "rb") as image_file:
content = image_file.read()
image = vision.Image(content=content)
response = client.text_detection(image=image)
if response.error.message:
raise Exception(
"{}\nFor more info on error messages, check: "
"https://cloud.google.com/apis/design/errors".format(response.error.message)
)
texts = response.text_annotations
return texts[0].description
# Initialize Translation client
def translate_text(text, project_id="myproject-capston"):
"""Translating Text."""
client = translate.TranslationServiceClient()
location = "global"
parent = f"projects/{project_id}/locations/{location}"
# Translate text from English to French
# Detail on supported types can be found here:
# https://cloud.google.com/translate/docs/supported-formats
response = client.translate_text(
request={
"parent": parent,
"contents": [text],
"mime_type": "text/plain", # mime types: text/plain, text/html
"source_language_code": "en-US",
"target_language_code": "ko",
}
)
# Display the translation for each input text provided
for translation in response.translations:
print("Translated text: {}".format(translation.translated_text))
번역된 결과물 자체는 잘 나오는거 같으나(python -m celery -A backend worker실행화면에서 translate_text()함수에 결과값을 print하도록 설정했더니 "Translated text: ~~~~ " 이렇게 콘솔에 잘 나타납니다) post.ocr_text필드상에 null값이 입력이 됩니다...
post.ocr_text필드속성에 null=True, blank=True 로 되어있고 비동기처리하기전에도 계속 null값이 들어가서(visionai와 translation이 시간이 좀 걸리다보니?) 비동기로 처리할려고 했는데도 여전히 null값이 들어가네요ㅜㅜ 어떻게 해결해야 할까요?? post.save()위치를 tasks.py안이나 views.py에서 비동기 작업은 조건문을 거는 방식 등등을 해보았으나 때에 따라서는 "ocr_text": "5f69b757-0f24-4cc4-947c-f8c624b48dde", 이런식으로 결과가 나오기도 하네요... 똑같은 사진인데도 매번 다른 16진수가 들어가던걸 확인했는데 번역된 결과값은 아닌거 같습니다...
아 추가적으로 코드를 바꿀때마다 celery worker은 매번 재시작하였습니다
맞습니다. :-)
파이썬 함수에서 아무 것도 반환하지 않으면, None을 리턴한 것으로 처리합니다.
잘 해결하셨습니다. 👍