"""Replace the blank regenerated template with the genuinely signed resolution. Uses the app's own upload endpoint so the same MIME/size validation and filename handling apply as when the operator uploads from the UI. """ import json import mimetypes import urllib.request import uuid from pathlib import Path BASE = "http://localhost:6001" SRC = Path( r"C:\Users\SJ\.minimax\v2\assets\2026\10\12\13-41-56-012-asset_20261012-134156-012_a0299b3ae338_88b7c484-UFC - Shareholders Resolution Director Sune Resigned.pdf" ) TARGETS = [ ("ysterbaard_resolutions", "e0dbxprazb70rqx", "signed_letter"), ("ysterbaard_director_resignations", "8cfie18uhgy0n0o", "signature"), ] def post_file(url: str, path: Path, field: str = "file", upload_name: str | None = None): boundary = uuid.uuid4().hex # The source file on disk carries an asset-slug prefix; send a clean name so # the stored file is recognisable in the PB admin UI and on the documents page. filename = upload_name or path.name ctype = mimetypes.guess_type(filename)[0] or "application/pdf" body = b"".join([ f"--{boundary}\r\n".encode(), f'Content-Disposition: form-data; name="{field}"; filename="{filename}"\r\n'.encode(), f"Content-Type: {ctype}\r\n\r\n".encode(), path.read_bytes(), f"\r\n--{boundary}--\r\n".encode(), ]) req = urllib.request.Request( url, data=body, method="POST", headers={"Content-Type": f"multipart/form-data; boundary={boundary}"}, ) with urllib.request.urlopen(req, timeout=180) as r: return json.loads(r.read().decode()) if not SRC.exists(): raise SystemExit(f"source file missing: {SRC}") print(f"source: {SRC.name} ({SRC.stat().st_size} bytes)") print() CLEAN_NAME = "UFC - Shareholders Resolution Director Sune Resigned.pdf" for collection, record_id, field in TARGETS: url = f"{BASE}/api/resolutions/{record_id}/upload?collection={collection}&field={field}" try: res = post_file(url, SRC, upload_name=CLEAN_NAME) print(f"OK {collection}.{field}") print(f" stored as: {res.get('stored')}") print(f" bytes: {res.get('bytes')}") except urllib.error.HTTPError as e: print(f"FAIL {collection}.{field}: HTTP {e.code} {e.read().decode()[:300]}") print()