Files
Anush edd213e923 refactor: upload improvements, centralize constants and cleanup imports
Upload Improvements:
- Standardize upload endpoint configuration in constants.py
- Centralize upload headers (x-tenant-id, x-goog-upload-protocol) in Headers.UPLOAD
- Update upload_file.py to reference Headers constants instead of hardcoded values

Code Cleanup:
- Remove unused imports from client.py (Task, GRPC, ImageGenerationError)
- Remove unused logger import from parsing.py
- Fix ImageStatus import for image mode status checking
2026-01-18 09:26:02 +05:30

149 lines
4.7 KiB
Python

from enum import Enum, IntEnum, StrEnum
class Endpoint(StrEnum):
GOOGLE = "https://www.google.com"
INIT = "https://gemini.google.com/app"
GENERATE = "https://gemini.google.com/_/BardChatUi/data/assistant.lamda.BardFrontendService/StreamGenerate"
ROTATE_COOKIES = "https://accounts.google.com/RotateCookies"
UPLOAD = "https://push.clients6.google.com/upload/"
BATCH_EXEC = "https://gemini.google.com/_/BardChatUi/data/batchexecute"
class GRPC(StrEnum):
"""
Google RPC ids used in Gemini API.
"""
# Chat methods
LIST_CHATS = "MaZiqc"
READ_CHAT = "hNvQHb"
# Gem methods
LIST_GEMS = "CNgdBe"
CREATE_GEM = "oMH3Zd"
UPDATE_GEM = "kHv0Vd"
DELETE_GEM = "UXcSJb"
# Content generation (batchexecute)
TEXT_GENERATE = "qpEbW" # Text/Chat generation
IMAGE_GENERATE = "aPya6c" # Image generation
HEARTBEAT = "ESY5D" # Session heartbeat
class Headers(Enum):
GEMINI = {
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
"Host": "gemini.google.com",
"Origin": "https://gemini.google.com",
"Referer": "https://gemini.google.com/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
"X-Same-Domain": "1",
"x-goog-ext-73010989-jspb": "[0]",
}
ROTATE_COOKIES = {
"Content-Type": "application/json",
}
UPLOAD = {
"Push-ID": "feeds/mcudyrk2a4khkz",
"x-goog-upload-protocol": "resumable",
"x-tenant-id": "bard-storage",
}
IMAGE_MODE = {
"x-goog-ext-525001261-jspb": "[1,null,null,null,null,null,null,0,[4],null,null,2]",
"x-goog-ext-73010989-jspb": "[0]",
}
BROWSER = {
"x-browser-channel": "stable",
"x-browser-copyright": "Copyright 2026 Google LLC. All Rights reserved.",
"x-browser-year": "2026",
}
class Model(Enum):
UNSPECIFIED = ("unspecified", {}, False)
G_3_0_PRO = (
"gemini-3-pro",
{
"x-goog-ext-525001261-jspb": '[1,null,null,null,"e6fa609c3fa255c0",null,null,0,[4],null,null,2]',
"x-goog-ext-73010989-jspb": "[0]",
},
False,
)
G_2_5_PRO = (
"gemini-3-thinking",
{
"x-goog-ext-525001261-jspb": '[1,null,null,null,"4af6c7f5da75d65d",null,null,0,[4],null,null,2]',
"x-goog-ext-73010989-jspb": "[0]",
},
False,
)
G_2_5_FLASH = (
"gemini-3-flash",
{
"x-goog-ext-525001261-jspb": '[1,null,null,null,"9ec249fc9ad08861",null,null,0,[4],null,null,2]',
"x-goog-ext-73010989-jspb": "[0]",
},
False,
)
def __init__(self, name, header, advanced_only):
self.model_name = name
self.model_header = header
self.advanced_only = advanced_only
@classmethod
def from_name(cls, name: str):
for model in cls:
if model.model_name == name:
return model
raise ValueError(
f"Unknown model name: {name}. Available models: {', '.join([model.model_name for model in cls])}"
)
@classmethod
def from_dict(cls, model_dict: dict):
if "model_name" not in model_dict or "model_header" not in model_dict:
raise ValueError(
"When passing a custom model as a dictionary, 'model_name' and 'model_header' keys must be provided."
)
if not isinstance(model_dict["model_header"], dict):
raise ValueError(
"When passing a custom model as a dictionary, 'model_header' must be a dictionary containing valid header strings."
)
custom_model = cls.UNSPECIFIED
custom_model.model_name = model_dict["model_name"]
custom_model.model_header = model_dict["model_header"]
return custom_model
class ErrorCode(IntEnum):
"""
Known error codes returned from server.
"""
CONTENT_SAFETY_3 = 3 # Safety filter rejection
CONTENT_SAFETY_4 = 4 # Safety filter rejection (alternate)
TEMPORARY_ERROR_1013 = 1013 # Randomly raised when generating with certain models, but disappears soon after
USAGE_LIMIT_EXCEEDED = 1037
MODEL_INCONSISTENT = 1050
MODEL_HEADER_INVALID = 1052
IP_TEMPORARILY_BLOCKED = 1060
class ImageStatus(IntEnum):
"""
Status codes for image generation response parsing.
Found at candidate[12][6][0] in the response structure.
"""
PENDING = 1 # Image generation started
IN_PROGRESS = 2 # Image generation in progress
COMPLETE = 3 # Image generation complete, images available
SAFETY_BLOCKED = 4 # Blocked by safety filters
ERROR = 5 # Generation failed