@@ -472,7 +472,12 @@ if (SENTRY_URL := env.str('SENTRY_URL', '')) and RELEASE and ENVIRONMENT: transaction_style='url', middleware_spans=True, signals_spans=True, cache_spans=False ), ], - ignore_errors=['InsufficientBalance', 'RequestBlocked'] + ignore_errors=[ + 'InsufficientBalance', + 'RequestBlocked', + 'PredictionInterruptedError', + 'ImageContentNotFound', + ], ) CACHEOPS_REDIS = env.str('CACHEOPS_REDIS', CACHES['default']['LOCATION']) @@ -11,7 +11,7 @@ from django.core.files import File from replicate.exceptions import ModelError from messages.models import Message -from ml_model.exceptions import ImageContentNotFound, GenerationException +from ml_model.exceptions import ImageContentNotFound, GenerationException, RequestBlocked from ml_model.services.base import SimpleService from ml_model.tasks import replicate_run @@ -23,7 +23,7 @@ class Nanobanana(SimpleService): '1K': Decimal('45'), '2K': Decimal('45'), '4K': Decimal('90'), - } + }, } def calculate_price(self, version: str, resolution: Optional[str]) -> Decimal: @@ -70,6 +70,8 @@ class Nanobanana(SimpleService): except ModelError as exc: if exc.prediction.error == 'No image content found in response': raise ImageContentNotFound + elif 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, version=version, resolution=resolution) @@ -7,8 +7,10 @@ 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.services.base import SimpleService from ml_model.tasks import replicate_run @@ -50,7 +52,12 @@ class Ray(SimpleService): input_message.file.close() callback_data.update({'start_image': image}) start_time = time.time() - video = replicate_run('luma/ray', callback_data) + try: + video = replicate_run('luma/ray', 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) msgs = self.save_results(input_message.content, process_time, video, save) @@ -1,5 +1,4 @@ import base64 -import logging import time from datetime import timedelta from decimal import Decimal @@ -8,9 +7,10 @@ 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.models import ModelCategory, ModelInput, ModelParameter +from ml_model.exceptions import RequestBlocked, GenerationException from ml_model.services.base import SimpleService from ml_model.tasks import replicate_run @@ -53,7 +53,12 @@ class Seedream(SimpleService): image = f'data:{mime};base64,{base64.b64encode(input_message.file.read()).decode("utf-8")}' input_message.file.close() callback_data.update({'image_input': [image]}) - images = replicate_run('bytedance/seedream-4', callback_data) + try: + images = replicate_run('bytedance/seedream-4', 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, max_images=len(images)) msgs = self.save_results(input_message.content, images, process_time, save) @@ -7,8 +7,10 @@ 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.services.base import SimpleService from ml_model.tasks import replicate_run @@ -17,10 +19,7 @@ from payments.selectors.payment_plan_selector import PaymentPlanSelector class Veo(SimpleService): - TOKENS_COST = { - 'veo-3': Decimal('640'), - 'veo-3-fast': Decimal('240') - } + TOKENS_COST = {'veo-3': Decimal('640'), 'veo-3-fast': Decimal('240')} def calculate_price(self, version: str) -> Decimal: return self.TOKENS_COST[version] @@ -38,7 +37,9 @@ class Veo(SimpleService): def make(self, input_message: Message, save: bool = True) -> list[Message]: version = input_message.info.pop('version', 'veo-3-fast') - if (balance := PaymentPlanSelector(self.store.user).get_current_balance()) < self.TOKENS_COST[version]: + if (balance := PaymentPlanSelector(self.store.user).get_current_balance()) < self.TOKENS_COST[ + version + ]: raise InsufficientBalance(balance, self.TOKENS_COST[version]) callback_data = dict({'prompt': input_message.content, **input_message.info}) if input_message.file: @@ -49,7 +50,12 @@ class Veo(SimpleService): input_message.file.close() callback_data.update({'image': image}) start_time = time.time() - video = replicate_run(f'google/{version}', callback_data) + try: + video = replicate_run(f'google/{version}', 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, version) msgs = self.save_results(input_message.content, process_time, video, save)