| """XAI asset management protocol — list / delete / download endpoints. |
| |
| URL reference (from production reverse analysis): |
| list GET https://grok.com/rest/assets |
| delete DELETE https://grok.com/rest/assets-metadata/{asset_id} |
| download GET https://assets.grok.com/{path} (streaming) |
| |
| The app-chat upload endpoint is handled separately in transport/asset_upload.py. |
| """ |
|
|
| import pathlib |
| import urllib.parse |
| from urllib.parse import urlparse |
|
|
| ASSETS_LIST_URL = "https://grok.com/rest/assets" |
| ASSETS_DELETE_URL = "https://grok.com/rest/assets-metadata" |
| ASSETS_DOWNLOAD_BASE = "https://assets.grok.com" |
|
|
| |
| APP_CHAT_UPLOAD_URL = "https://grok.com/rest/app-chat/upload-file" |
|
|
| |
| _EXTENSION_MIME: dict[str, str] = { |
| ".jpg": "image/jpeg", |
| ".jpeg": "image/jpeg", |
| ".png": "image/png", |
| ".webp": "image/webp", |
| ".mp4": "video/mp4", |
| ".webm": "video/webm", |
| } |
|
|
| def asset_delete_url(asset_id: str) -> str: |
| return f"{ASSETS_DELETE_URL}/{asset_id}" |
|
|
|
|
| def resolve_download_url(file_path: str) -> tuple[str, str, str]: |
| """Resolve *file_path* to ``(url, origin, referer)``. |
| |
| *file_path* may be: |
| - a full ``https://assets.grok.com/...`` URL |
| - an absolute path ``/foo/bar.png`` |
| - a relative path ``foo/bar.png`` |
| """ |
| parsed = urlparse(file_path) |
| if parsed.scheme and parsed.netloc: |
| url = file_path |
| origin = f"{parsed.scheme}://{parsed.netloc}" |
| else: |
| path = file_path if file_path.startswith("/") else f"/{file_path}" |
| url = f"{ASSETS_DOWNLOAD_BASE}{path}" |
| origin = ASSETS_DOWNLOAD_BASE |
| return url, origin, f"{origin}/" |
|
|
|
|
| def infer_content_type(url: str) -> str | None: |
| """Return a best-guess MIME type for *url* based on file extension.""" |
| path = pathlib.Path(urllib.parse.urlparse(url).path) |
| return _EXTENSION_MIME.get(path.suffix.lower()) |
|
|
|
|
| def resolve_asset_reference( |
| file_id: str, |
| file_uri: str, |
| *, |
| user_id: str | None = None, |
| ) -> str | None: |
| """Return the absolute asset content URL used by image-edit requests.""" |
| if file_uri: |
| url, _, _ = resolve_download_url(file_uri) |
| return url |
| if file_id and user_id: |
| return f"{ASSETS_DOWNLOAD_BASE}/users/{user_id}/{file_id}/content" |
| return None |
|
|
|
|
| __all__ = [ |
| "ASSETS_LIST_URL", "ASSETS_DELETE_URL", "ASSETS_DOWNLOAD_BASE", |
| "APP_CHAT_UPLOAD_URL", |
| "asset_delete_url", "resolve_download_url", "infer_content_type", |
| "resolve_asset_reference", |
| ] |
|
|