@@ -477,6 +477,7 @@ if (SENTRY_URL := env.str('SENTRY_URL', '')) and RELEASE and ENVIRONMENT: 'RequestBlocked', 'PredictionInterruptedError', 'ImageContentNotFound', + 'PromptLengthExceeded' ], ) @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-25 15:54+0300\n" +"POT-Creation-Date: 2026-01-12 11:29+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -670,6 +670,11 @@ msgstr "При выбранном стиле используйте тип ст msgid "Prediction interrupted. Please retry again" msgstr "Генерация прервана. Пожалуйста, повторите попытку еще раз" +#: ml_model/exceptions.py:104 +#, python-format +msgid "Prompt is too long. Maximum length is %(max_length)s characters." +msgstr "Промпт слишком длинный. Максимальная длина — %(max_length)s символов." + #: ml_model/models.py:18 ml_model/models.py:38 ml_model/models.py:70 #: ml_model/models.py:182 tools/media/models.py:43 msgid "Slug" @@ -6,6 +6,7 @@ from asgiref.sync import async_to_sync from googletrans import Translator from messages.models import BaseStore, Message +from ml_model.exceptions import PromptLengthExceeded from ml_model.models import ( ModelCategory, ModelInput, @@ -56,6 +57,8 @@ class SimpleService(ABC): ) def translate_prompt(self, prompt: str, to: str = 'en'): + if len(prompt) > 3000: + raise PromptLengthExceeded return async_to_sync(self.translator.translate)(prompt, dest=to).text @abstractmethod @@ -94,3 +94,13 @@ class InvalidStyleCombinationError(Exception): class PredictionInterruptedError(Exception): def __str__(self): return _('Prediction interrupted. Please retry again') + + +class PromptLengthExceeded(Exception): + def __init__(self, max_length: int = 3000) -> None: + self.max_length = max_length + + def __str__(self) -> str: + return _('Prompt is too long. Maximum length is %(max_length)s characters.') % { + 'max_length': self.max_length + } @@ -26,6 +26,7 @@ from ml_model.exceptions import ( TemplateNotFound, TemplateUnknownException, RequestBlocked, + PromptLengthExceeded, ) from ml_model.services.base import SimpleService from payments.exceptions.insufficient_balance import InsufficientBalance @@ -163,7 +164,12 @@ class MessagesAPIView(APIView): {'detail': f'{exc}'}, status=HTTP_503_SERVICE_UNAVAILABLE, ) - except (FileExtensionNotSupported, ExceededContextLengthError, RequestBlocked) as exc: + except ( + FileExtensionNotSupported, + ExceededContextLengthError, + RequestBlocked, + PromptLengthExceeded, + ) as exc: return Response({'detail': f'{exc}'}, status=HTTP_400_BAD_REQUEST) except TemplateNotFound as exc: return Response({'detail': f'{exc}'}, status=HTTP_500_INTERNAL_SERVER_ERROR) @@ -15,7 +15,8 @@ from ml_model.exceptions import ( UnsupportedSize, FileNotProvided, ImageContentNotFound, - InvalidStyleCombinationError + InvalidStyleCombinationError, + PromptLengthExceeded, ) from ml_model.models import NeuronModel from ml_model.services.base import SimpleService @@ -158,9 +159,17 @@ class MediaAPIView(APIView): input_message.save() if isinstance(exc, InsufficientBalance): return Response({'detail': f'{exc}'}, status=HTTP_402_PAYMENT_REQUIRED) - if isinstance(exc, ( - UnsupportedSize, RequestBlocked, FileNotProvided, ImageContentNotFound, InvalidStyleCombinationError - )): + if isinstance( + exc, + ( + UnsupportedSize, + RequestBlocked, + FileNotProvided, + ImageContentNotFound, + InvalidStyleCombinationError, + PromptLengthExceeded, + ), + ): return Response({'detail': f'{exc}'}, status=HTTP_400_BAD_REQUEST) return Response( {