feat: Add logging to API endpoints, update generation response model, and refine project configurations.

This commit is contained in:
xds
2026-02-05 15:29:31 +03:00
parent 9ae6e8e08e
commit 736e5a8c12
55 changed files with 244 additions and 35 deletions

View File

@@ -1,3 +1,4 @@
class GoogleGenerationException(Exception):
message: str
pass
def __init__(self, message: str):
self.message = message
super().__init__(message)

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
import io
import logging
from datetime import datetime
from typing import List, Union
from typing import List, Union, Tuple, Dict, Any
from PIL import Image
from google import genai
@@ -27,6 +27,7 @@ class GoogleAdapter:
"""Вспомогательный метод для подготовки контента (текст + картинки)"""
contents = [prompt]
if images_list:
logger.info(f"Preparing content with {len(images_list)} images")
for img_bytes in images_list:
try:
# Gemini API требует PIL Image на входе
@@ -34,6 +35,8 @@ class GoogleAdapter:
contents.append(image)
except Exception as e:
logger.error(f"Error processing input image: {e}")
else:
logger.info("Preparing content with no images")
return contents
def generate_text(self, prompt: str, images_list: List[bytes] = None) -> str:
@@ -59,20 +62,25 @@ class GoogleAdapter:
for part in response.parts:
if part.text:
result_text += part.text
logger.error(f"Generated text: {result_text}")
logger.info(f"Generated text length: {len(result_text)}")
return result_text
except Exception as e:
logger.error(f"Gemini Text API Error: {e}")
return f"Ошибка генерации текста: {e}"
raise GoogleGenerationException(f"Gemini Text API Error: {e}")
def generate_image(self, prompt: str, aspect_ratio: AspectRatios, quality: Quality, images_list: List[bytes] = None, ) -> List[io.BytesIO]:
def generate_image(self, prompt: str, aspect_ratio: AspectRatios, quality: Quality, images_list: List[bytes] = None, ) -> Tuple[List[io.BytesIO], Dict[str, Any]]:
"""
Генерация изображений (Text-to-Image или Image-to-Image).
Возвращает список байтовых потоков (готовых к отправке).
"""
contents = self._prepare_contents(prompt, images_list)
contents = self._prepare_contents(prompt, images_list)
logger.info(f"Generating image. Prompt length: {len(prompt)}, Ratio: {aspect_ratio}, Quality: {quality}")
start_time = datetime.now()
token_usage = 0
try:
response = self.client.models.generate_content(
model=self.IMAGE_MODEL,
@@ -86,6 +94,13 @@ class GoogleAdapter:
),
)
)
end_time = datetime.now()
api_duration = (end_time - start_time).total_seconds()
if response.usage_metadata:
token_usage = response.usage_metadata.total_token_count
if response.parts is None and response.candidates[0].finish_reason is not None:
raise GoogleGenerationException(f"Generation blocked in cause of {response.candidates[0].finish_reason.value}")
@@ -111,9 +126,17 @@ class GoogleAdapter:
except Exception as e:
logger.error(f"Error processing output image: {e}")
return generated_images
if generated_images:
logger.info(f"Successfully generated {len(generated_images)} images in {api_duration:.2f}s. Tokens: {token_usage}")
else:
logger.warning("No images text generated from parts")
metrics = {
"api_execution_time_seconds": api_duration,
"token_usage": token_usage
}
return generated_images, metrics
except Exception as e:
logger.error(f"Gemini Image API Error: {e}")
# В случае ошибки возвращаем пустой список (или можно рейзить исключение)
return []
raise GoogleGenerationException(f"Gemini Image API Error: {e}")