Skip to content

Instantly share code, notes, and snippets.

@Reelix
Created October 14, 2026 07:50
Show Gist options
  • Select an option

  • Save Reelix/f46504e754b549558f50dc37c9f3fe0a to your computer and use it in GitHub Desktop.

Select an option

Save Reelix/f46504e754b549558f50dc37c9f3fe0a to your computer and use it in GitHub Desktop.
Download IPA from Firebase given Firebase itms-services:// link
#!/usr/bin/env python3
import os
import re
import sys
import urllib.parse
import urllib.request
def extract_app_info(raw_link: str):
# Unquote the outer layer to expose query parameters
unquoted = urllib.parse.unquote(raw_link)
# Get the display name
name_match = re.search(r'[?&]display_name=([^&]+)', unquoted)
raw_name = name_match.group(1) if name_match else "app"
clean_name = re.sub(r'[\\/*?:"<>|]', "", raw_name).strip()
filename = f"{clean_name}.ipa"
# Get the direct download link
uri_match = re.search(r'[?&]download_uri=(https?://[^&]+)', unquoted)
if not uri_match:
raise ValueError("Could not find 'download_uri' in the provided link.")
# Second unquote decodes the inner token parameters (%253D -> %3D -> =)
curl_link = urllib.parse.unquote(uri_match.group(1))
return filename, curl_link
def download_ipa(url: str, output_filename: str):
# Stream the IPA directly to disk
req = urllib.request.Request(url, headers={"User-Agent": "curl/7.88.1"})
with urllib.request.urlopen(req) as response, open(output_filename, "wb") as f:
total_size = response.getheader("Content-Length")
total_size = int(total_size) if total_size else None
downloaded = 0
chunk_size = 1024 * 1024 # 1 MB
while True:
chunk = response.read(chunk_size)
if not chunk:
break
downloaded += len(chunk)
f.write(chunk)
if total_size:
pct = (downloaded / total_size) * 100
mb = downloaded / (1024 * 1024)
total_mb = total_size / (1024 * 1024)
sys.stdout.write(f"\rDownloading: {pct:5.1f}% [{mb:6.1f} / {total_mb:6.1f} MB]")
else:
mb = downloaded / (1024 * 1024)
sys.stdout.write(f"\rDownloading: {mb:6.1f} MB")
sys.stdout.flush()
print(f"\nDone! File saved as: {output_filename}")
def main():
raw_link = sys.argv[1] if len(sys.argv) > 1 else input("Enter URL: ").strip()
try:
filename, curl_link = extract_app_info(raw_link)
print(f"\n[1] App Name : {filename}")
print(f"[2] Direct URL: {curl_link}\n")
print(f"[3] Downloading {filename}...")
download_ipa(curl_link, filename)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment