litellm-mirror/litellm/llms/prompt_templates/image_handling.py
Krish Dholakia d57be47b0f
Litellm ruff linting enforcement (#5992)
* ci(config.yml): add a 'check_code_quality' step

Addresses https://github.com/BerriAI/litellm/issues/5991

* ci(config.yml): check why circle ci doesn't pick up this test

* ci(config.yml): fix to run 'check_code_quality' tests

* fix(__init__.py): fix unprotected import

* fix(__init__.py): don't remove unused imports

* build(ruff.toml): update ruff.toml to ignore unused imports

* fix: fix: ruff + pyright - fix linting + type-checking errors

* fix: fix linting errors

* fix(lago.py): fix module init error

* fix: fix linting errors

* ci(config.yml): cd into correct dir for checks

* fix(proxy_server.py): fix linting error

* fix(utils.py): fix bare except

causes ruff linting errors

* fix: ruff - fix remaining linting errors

* fix(clickhouse.py): use standard logging object

* fix(__init__.py): fix unprotected import

* fix: ruff - fix linting errors

* fix: fix linting errors

* ci(config.yml): cleanup code qa step (formatting handled in local_testing)

* fix(_health_endpoints.py): fix ruff linting errors

* ci(config.yml): just use ruff in check_code_quality pipeline for now

* build(custom_guardrail.py): include missing file

* style(embedding_handler.py): fix ruff check
2024-10-01 19:44:20 -04:00

87 lines
2.5 KiB
Python

"""
Helper functions to handle images passed in messages
"""
import base64
from httpx import Response
import litellm
from litellm import verbose_logger
from litellm.caching import InMemoryCache
from litellm.llms.custom_httpx.http_handler import (
_get_httpx_client,
get_async_httpx_client,
)
MAX_IMGS_IN_MEMORY = 10
in_memory_cache = InMemoryCache(max_size_in_memory=MAX_IMGS_IN_MEMORY)
def _process_image_response(response: Response, url: str) -> str:
if response.status_code != 200:
raise Exception(
f"Error: Unable to fetch image from URL. Status code: {response.status_code}, url={url}"
)
image_bytes = response.content
base64_image = base64.b64encode(image_bytes).decode("utf-8")
image_type = response.headers.get("Content-Type")
if image_type is None:
img_type = url.split(".")[-1].lower()
_img_type = {
"jpg": "image/jpeg",
"jpeg": "image/jpeg",
"png": "image/png",
"gif": "image/gif",
"webp": "image/webp",
}.get(img_type)
if _img_type is None:
raise Exception(
f"Error: Unsupported image format. Format={_img_type}. Supported types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']"
)
img_type = _img_type
else:
img_type = image_type
result = f"data:{img_type};base64,{base64_image}"
in_memory_cache.set_cache(url, result)
return result
async def async_convert_url_to_base64(url: str) -> str:
cached_result = in_memory_cache.get_cache(url)
if cached_result:
return cached_result
client = litellm.module_level_aclient
for _ in range(3):
try:
response = await client.get(url, follow_redirects=True)
return _process_image_response(response, url)
except Exception:
pass
raise Exception(
f"Error: Unable to fetch image from URL after 3 attempts. url={url}"
)
def convert_url_to_base64(url: str) -> str:
cached_result = in_memory_cache.get_cache(url)
if cached_result:
return cached_result
client = litellm.module_level_client
for _ in range(3):
try:
response = client.get(url, follow_redirects=True)
return _process_image_response(response, url)
except Exception as e:
verbose_logger.exception(e)
# print(e)
pass
raise Exception(
f"Error: Unable to fetch image from URL after 3 attempts. url={url}"
)