Skip to content

Instantly share code, notes, and snippets.

@chhaugen
Created April 8, 2026 20:48
Show Gist options
  • Select an option

  • Save chhaugen/490a3902f67b35a8c5b430e70ecc0507 to your computer and use it in GitHub Desktop.

Select an option

Save chhaugen/490a3902f67b35a8c5b430e70ecc0507 to your computer and use it in GitHub Desktop.
import requests
import os
import re
download_folder = r"<lokal mappe sti>"
os.makedirs(download_folder, exist_ok=True)
# F12 på apex, finn api-forespørselen som ligner, bytt ut leilighetsnummeret.
# I Request headers feltet, finn cookies og lim det inn under også.
root_folder_url = "https://api.apexapp.io/project/1899/apartment/<ditt leilighetsnummer>/mom"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:149.0) Gecko/20100101 Firefox/149.0",
"Accept": "application/json, text/plain, */*",
"Accept-Language": "nb,no;q=0.9,en-US;q=0.8,en;q=0.7",
"content-type": "application/json",
"Origin": "https://portal.apexapp.io",
"Referer": "https://portal.apexapp.io/",
"Cookie": "<Dine cookies>",
"Sec-Fetch-Dest": "empty",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Site": "same-site",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
"TE": "trailers",
}
def sanitize_windows_filename(name: str, replacement: str = "_") -> str:
# Replace invalid characters
name = re.sub(r'[<>:"/\\|?*]', replacement, name)
# Remove trailing spaces and dots
name = name.rstrip(" .")
# Handle reserved names (case-insensitive)
reserved_names = {
"CON", "PRN", "AUX", "NUL",
*(f"COM{i}" for i in range(1, 10)),
*(f"LPT{i}" for i in range(1, 10)),
}
if name.upper() in reserved_names:
name = f"{name}{replacement}"
# Prevent empty name
if not name:
name = "untitled"
return name
def download_file(file_object, local_folder_path):
signed = file_object["signed"]
download_url = signed["url"]
local_file_path = local_folder_path + "/" + sanitize_windows_filename(file_object["name"])
respnse = requests.get(download_url)
print(f"Downloading: {local_file_path}")
with open(local_file_path, "wb") as local_file:
local_file.write(respnse.content)
print(f"Downloaded: {local_file_path}")
def download_folder_recursivly(folder_object, parent_local_folder_path):
local_folder_path = parent_local_folder_path + "/" + sanitize_windows_filename(folder_object["name"])
files = folder_object["Files"]
folders = folder_object["Children"]
if len(files) == 0 and len(folders) == 0:
print(f"Empty folder: {local_folder_path}")
return
os.makedirs(local_folder_path, exist_ok=True)
for file in files:
download_file(file, local_folder_path)
for folder in folders:
folder_id = folder["id"]
folder_url = root_folder_url + "/" + folder_id
folder_response = requests.get(folder_url, headers=headers)
child_folder_object = folder_response.json()["Entity"]
download_folder_recursivly(child_folder_object, local_folder_path)
root_folder_response = requests.get(root_folder_url, headers=headers)
root_folder = root_folder_response.json()["Entity"]
download_folder_recursivly(root_folder, download_folder)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment