Spaces:
Paused
Paused
| import io | |
| import json | |
| from os import PathLike | |
| from typing import Optional | |
| from litellm.types.llms.openai import FileTypes, OpenAIFilesPurpose | |
| class InMemoryFile(io.BytesIO): | |
| def __init__(self, content: bytes, name: str): | |
| super().__init__(content) | |
| self.name = name | |
| def should_replace_model_in_jsonl( | |
| purpose: OpenAIFilesPurpose, | |
| ) -> bool: | |
| """ | |
| Check if the model name should be replaced in the JSONL file for the deployment model name. | |
| Azure raises an error on create batch if the model name for deployment is not in the .jsonl. | |
| """ | |
| if purpose == "batch": | |
| return True | |
| return False | |
| def replace_model_in_jsonl(file_content: FileTypes, new_model_name: str) -> FileTypes: | |
| try: | |
| ## if pathlike, return the original file content | |
| if isinstance(file_content, PathLike): | |
| return file_content | |
| # Decode the bytes to a string and split into lines | |
| # If file_content is a file-like object, read the bytes | |
| if hasattr(file_content, "read"): | |
| file_content_bytes = file_content.read() # type: ignore | |
| elif isinstance(file_content, tuple): | |
| file_content_bytes = file_content[1] | |
| else: | |
| file_content_bytes = file_content | |
| # Decode the bytes to a string and split into lines | |
| if isinstance(file_content_bytes, bytes): | |
| file_content_str = file_content_bytes.decode("utf-8") | |
| elif isinstance(file_content_bytes, str): | |
| file_content_str = file_content_bytes | |
| else: | |
| return file_content | |
| lines = file_content_str.splitlines() | |
| modified_lines = [] | |
| for line in lines: | |
| # Parse each line as a JSON object | |
| json_object = json.loads(line.strip()) | |
| # Replace the model name if it exists | |
| if "body" in json_object: | |
| json_object["body"]["model"] = new_model_name | |
| # Convert the modified JSON object back to a string | |
| modified_lines.append(json.dumps(json_object)) | |
| # Reassemble the modified lines and return as bytes | |
| modified_file_content = "\n".join(modified_lines).encode("utf-8") | |
| return InMemoryFile(modified_file_content, name="modified_file.jsonl") # type: ignore | |
| except (json.JSONDecodeError, UnicodeDecodeError, TypeError): | |
| # return the original file content if there is an error replacing the model name | |
| return file_content | |
| def _get_router_metadata_variable_name(function_name: Optional[str]) -> str: | |
| """ | |
| Helper to return what the "metadata" field should be called in the request data | |
| For all /thread or /assistant endpoints we need to call this "litellm_metadata" | |
| For ALL other endpoints we call this "metadata | |
| """ | |
| ROUTER_METHODS_USING_LITELLM_METADATA = set( | |
| ["batch", "generic_api_call", "_acreate_batch", "file"] | |
| ) | |
| if function_name and any( | |
| method in function_name for method in ROUTER_METHODS_USING_LITELLM_METADATA | |
| ): | |
| return "litellm_metadata" | |
| else: | |
| return "metadata" | |