inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

댓글 쓰기 화면 및 API 구현

celery을 이용해서 비동기처리를 수행하는데 질문입니다!

해결된 질문

521

꺼넝

작성한 질문수 8

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은 매번 재시작하였습니다

react python django docker

답변 1

0

꺼넝

아... 해결했습니다... 제가 잘못했네요 디버깅하다보니 발견했는데 translate_text()함수에 return을 안했네요! 하하

0

이진석

맞습니다. :-)

파이썬 함수에서 아무 것도 반환하지 않으면, None을 리턴한 것으로 처리합니다.

잘 해결하셨습니다. 👍

안녕하세요.

0

48

1

[OneToOne Field Demo] get_user_model() 메서드를 활용해야 하는 이유?

0

272

1

useEffect 훅에서 else 유무에 따른 결과

0

211

1

useAxios 훅의 dependency array 설정

0

245

1

useEffect에서 변수 업데이트 관련 질문

0

381

1

rest_framework.generics.CreateAPIView의 model 속성 유무

0

266

1

bootstrap4

0

470

4

리뉴얼 강의가 오픈이 되면 기존 강의는 더이상 못보는걸까요

1

362

1

admin form에서 앞선 필드 선택 후 다른 필드 select widget 구성하는 방법

0

572

3

useState는 필수일까요?

0

261

1

python manage.py makemigrations instagram 시 created_at default 오류가 발생합니다.

0

596

4

Django allauth를 사용한 소셜 로그인 시 에러

0

654

1

프로젝트명 변경 뒤, 디버그툴바+디버그모드 사용 시 에러

0

552

2

useLocalStorage() 함수 사용여부

0

228

1

django에 LOGIN_URL = '/accounts/login/'의 의미?

0

447

1

리듀서의 의미 재확인

0

430

1

simple-jwt Refresh Token 사용 노하우

0

897

2

docker compose 를 통한 배포 관련 오류 문의

0

670

1

파이썬 속도 장고 관련 궁금한게 있습니다.

0

364

1

is_like_user

0

233

1

related_name 오류

0

272

1

re_path 오류

0

258

1

re_path url

0

249

1

No post matches the given query

0

659

2