@@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-12-25 13:42+0300\n" +"POT-Creation-Date: 2025-12-25 15:54+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -97,7 +97,7 @@ msgid "Domain not found" msgstr "Домен не найден" #: authentication/models/business_account.py:16 payments/models/promocode.py:72 -#: tools/public_api/models.py:34 +#: tools/public_api/models.py:34 tools/public_api/services/api_key.py:24 msgid "Owner" msgstr "Владелец" @@ -212,6 +212,7 @@ msgstr "ОГРН" #: authentication/models/business_host.py:69 ml_model/models.py:180 #: payments/models/payment_plan_feature.py:18 tools/public_api/models.py:31 +#: tools/public_api/services/api_key.py:24 msgid "Name" msgstr "Наименование" @@ -574,12 +575,13 @@ msgstr "" msgid "Token is invalid" msgstr "" -#: core/exceptions.py:5 +#: lib/exceptions.py:7 msgid "An unknown error has occurred. Please contact support" msgstr "" "Произошла неизвестная ошибка. Пожалуйста, обратитесь в службу поддержки" -#: lib/exceptions.py:15 +#: lib/exceptions.py:16 +#, python-format msgid "A %(model)s with fields %(fields)s already exists" msgstr "Уже существует %(model)s с полями %(fields)s" @@ -597,12 +599,12 @@ msgstr "Версия %(version)s уже имеет входные данные msgid "Neuron Models" msgstr "Нейронные Модели" -#: ml_model/exceptions.py:17 +#: ml_model/exceptions.py:18 msgid "The model is currently disabled. Please try again later." msgstr "" "Модель в настоящее время неактивна. Пожалуйста, повторите попытку позже." -#: ml_model/exceptions.py:22 +#: ml_model/exceptions.py:23 msgid "Your request was blocked by our moderation system" msgstr "Ваш запрос был заблокирован нашей системой модерации" @@ -615,18 +617,18 @@ msgstr "" "Размер изображения %(cw)dx%(ch)d не поддерживается. Пожалуйста, переверните " "до %(rw)dx%(rh)d" -#: ml_model/exceptions.py:37 +#: ml_model/exceptions.py:36 #, python-format msgid "Image size %(cw)sx%(ch)s is not supported. Required size: %(rw)sx%(rh)s" msgstr "" "Размер изображения %(cw)sx%(ch)s не поддерживается. Требуемый размер: " "%(rw)sx%(rh)s" -#: ml_model/exceptions.py:42 +#: ml_model/exceptions.py:43 msgid "The model is not responding" msgstr "Модель не отвечает" -#: ml_model/exceptions.py:51 +#: ml_model/exceptions.py:52 #, python-format msgid "" "The attached file format is not supported. Available formats: " @@ -635,35 +637,39 @@ msgstr "" "Формат вложенного файла не поддерживается. Доступные форматы: " "%(available_extensions)s." -#: ml_model/exceptions.py:57 +#: ml_model/exceptions.py:58 msgid "The length of the context has been exceeded." msgstr "Длина контекста превышена." -#: ml_model/exceptions.py:62 +#: ml_model/exceptions.py:63 msgid "Jinja template not found" msgstr "Jinja-шаблон не найден" -#: ml_model/exceptions.py:67 +#: ml_model/exceptions.py:68 msgid "There was an unknown error while rendering a template" msgstr "При рендеринге шаблона произошла неизвестная ошибка" -#: ml_model/exceptions.py:72 +#: ml_model/exceptions.py:73 msgid "The neuron model does not exist" msgstr "Нейронная модель не существует" -#: ml_model/exceptions.py:80 +#: ml_model/exceptions.py:81 #, python-format msgid "The %(file_type)s is not attached" msgstr "Файл (%(file_type)s) не прикреплен" -#: ml_model/exceptions.py:85 +#: ml_model/exceptions.py:86 msgid "No image content found in response. Try a different request" msgstr "В промпте отсутствует описание изображения. Попробуйте другой запрос" -#: ml_model/exceptions.py:90 +#: ml_model/exceptions.py:91 msgid "Use style type AUTO or GENERAL when a style preset is selected" msgstr "При выбранном стиле используйте тип стиля AUTO или GENERAL" +#: ml_model/exceptions.py:96 +msgid "Prediction interrupted. Please retry again" +msgstr "Генерация прервана. Пожалуйста, повторите попытку еще раз" + #: 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" @@ -9,8 +9,10 @@ import filetype import requests from django.core.files import File from django.core.files.images import get_image_dimensions +from replicate.exceptions import ModelError from messages.models import Message +from ml_model.exceptions import PredictionInterruptedError, RequestBlocked, GenerationException from ml_model.services.base import SimpleService from ml_model.tasks import replicate_run @@ -85,7 +87,14 @@ class Flux_2(SimpleService): image = f'data:{mime};base64,{base64.b64encode(input_message.file.read()).decode("utf-8")}' input_message.file.close() callback_data.update({'input_images': [image]}) - images = [replicate_run(f'black-forest-labs/{version}', callback_data)] + try: + images = [replicate_run(f'black-forest-labs/{version}', callback_data)] + except ModelError as exc: + if any(error in str(exc) for error in ('E005', 'E006', 'sexual')): + raise RequestBlocked + elif 'PA' in str(exc): + raise PredictionInterruptedError + raise GenerationException from exc process_time = timedelta(seconds=(time.time() - start_time)) self.handle_invoice(input_message.content_object.model, version=version, input_mp=input_mp, output_mp=output_mp) msgs = self.save_results(input_message.content, images, process_time, save) @@ -11,7 +11,7 @@ from django.core.files import File from messages.models import Message -from ml_model.exceptions import ModelTimeoutError +from ml_model.exceptions import ModelTimeoutError, GenerationException from ml_model.services.base import SimpleService @@ -89,14 +89,17 @@ class Fluxlorafast(SimpleService): f'fal-ai/{version}', json={'prompt': input_message.content, **callback_data}, ).json() - while True: - status = client.get(result['status_url']).json() - if status.get('status') == 'COMPLETED': - break - requests_number += 1 - if requests_number == 271: - raise ModelTimeoutError - time.sleep(1/3) + try: + while True: + status = client.get(result['status_url']).json() + if status.get('status') == 'COMPLETED': + break + requests_number += 1 + if requests_number == 271: + raise ModelTimeoutError + time.sleep(1/3) + except Exception as exc: + raise GenerationException from exc process_time = timedelta(seconds=(time.time() - start_time)) final_result = client.get(result['response_url']).json() images = [img['url'] for img in final_result['images']] @@ -5,9 +5,10 @@ from io import BytesIO import requests from django.core.files import File +from replicate.exceptions import ModelError from messages.models import Message -from ml_model.exceptions import InvalidStyleCombinationError +from ml_model.exceptions import InvalidStyleCombinationError, RequestBlocked, GenerationException from ml_model.models import ( NeuronModel, ) @@ -73,10 +74,15 @@ class Ideogram(SimpleService): **input_message.info, } ) - runner = replicate_run( - f'{self._CALLBACK_BASE}{callback_data.get("version", "ideogram-v3-turbo")}', - callback_data, - ) + try: + runner = replicate_run( + f'{self._CALLBACK_BASE}{callback_data.get("version", "ideogram-v3-turbo")}', + callback_data, + ) + except ModelError as exc: + if any(error in str(exc) for error in ('E005', 'E006', 'sexual')): + raise RequestBlocked + raise GenerationException from exc images = runner if isinstance(runner, list) else [runner] process_time = timedelta(seconds=(time.time() - start_time)) self.handle_invoice(input_message.content_object.model, input_message=input_message, version=version) @@ -4,11 +4,12 @@ from datetime import timedelta from decimal import Decimal from io import BytesIO -import filetype import requests from django.core.files import File +from replicate.exceptions import ModelError from messages.models import Message +from ml_model.exceptions import RequestBlocked, GenerationException from ml_model.models import ( NeuronModel, ) @@ -71,10 +72,15 @@ class Leonardo(SimpleService): **input_message.info, } ) - runner = replicate_run( - f'{self._CALLBACK_BASE}{callback_data.get("version", "lucid-origin")}', - callback_data, - ) + try: + runner = replicate_run( + f'{self._CALLBACK_BASE}{callback_data.get("version", "lucid-origin")}', + callback_data, + ) + except ModelError as exc: + if any(error in str(exc) for error in ('E005', 'E006', 'sexual')): + raise RequestBlocked + raise GenerationException from exc images = runner if isinstance(runner, list) else [runner] process_time = timedelta(seconds=(time.time() - start_time)) self.handle_invoice(input_message.content_object.model, input_message=input_message, version=version) @@ -5,8 +5,10 @@ from io import BytesIO import requests from django.core.files import File +from replicate.exceptions import ModelError from messages.models import Message +from ml_model.exceptions import RequestBlocked, GenerationException from ml_model.services.base import SimpleService from ml_model.tasks import replicate_run from payments.exceptions.insufficient_balance import InsufficientBalance @@ -42,7 +44,12 @@ class Lyria(SimpleService): **input_message.info } start_time = time.time() - video = replicate_run(f'google/lyria-2', callback_data) + try: + video = replicate_run(f'google/lyria-2', callback_data) + except ModelError as exc: + if any(error in str(exc) for error in ('E005', 'E006', 'sexual')): + raise RequestBlocked + raise GenerationException from exc process_time = timedelta(seconds=(time.time() - start_time)) self.handle_invoice(input_message.content_object.model, duration=32) msgs = self.save_results(input_message.content, process_time, video, save) @@ -1,6 +1,7 @@ from django.utils.translation import gettext as _ # накинуть перевод через gettext_lazy + class GenerationException(Exception): def __str__(self): return 'Случилась ошибка во время генерации у этой модели, пожалуйста повторите попытку позже' @@ -29,13 +30,13 @@ class UnsupportedSize(Exception): def __str__(self): if tuple(self.current_size.values()) == tuple(reversed(self.required_size.values())): - return _( - 'Image size %(cw)dx%(ch)d is not supported. ' - 'Please rotate image to %(rw)dx%(rh)d' - ) % (self.current_size | self.required_size) - return _( - 'Image size %(cw)sx%(ch)s is not supported. Required size: %(rw)sx%(rh)s' - ) % (self.current_size | self.required_size) + return _('Image size %(cw)dx%(ch)d is not supported. Please rotate image to %(rw)dx%(rh)d') % ( + self.current_size | self.required_size + ) + return _('Image size %(cw)sx%(ch)s is not supported. Required size: %(rw)sx%(rh)s') % ( + self.current_size | self.required_size + ) + class ModelTimeoutError(Exception): def __str__(self): @@ -88,3 +89,8 @@ class ImageContentNotFound(Exception): class InvalidStyleCombinationError(Exception): def __str__(self) -> str: return _('Use style type AUTO or GENERAL when a style preset is selected') + + +class PredictionInterruptedError(Exception): + def __str__(self): + return _('Prediction interrupted. Please retry again')