"""Render the complete HF card from the canonical GitHub README.
Preserve remote metadata, the featured film and frozen neural weights. Default
mode only prepares artifacts on D; --publish explicitly updates the HF card,
matching existing inference wrapper/docs and this small reproduction utility.
No forecasts are rerun, no media are regenerated and no neural modules change.
"""
from __future__ import annotations
import argparse
import hashlib
import html
import json
import re
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
REPO = 'euler314/typhoon-predict'
MEDIA_REVISION = '87a6e366b42bb4cc0edc95d2c50c55fca21a2c93'
CACHE = '/Volumes/D/typhoon_predict/.cache/huggingface-intensity'
HF = 'https://huggingface.co/' + REPO
FILMS = ('mangkhut',)
CURRENT_FIGURES = frozenset((
'evaluation/released_daily/model_1_2_benchmark.png',
'evaluation/released_daily/model_1_2_after_2024_benchmark.png',
'evaluation/released_daily/model_1_2_before_2024_benchmark.png',
'docs/trackformer_1_2_architecture.svg',
))
SYNC_FILES = (
'models/trackformer_1_2_field/README.md',
'models/trackformer_1_2_field/WIND_ESTIMATION.md',
'models/trackformer_1_2_field/predict.py',
'models/trackformer_1_2_field/plot_pressure.py',
'models/trackformer_1_2_field/wind_estimation.py',
'release_tools/sync_public_model_cards.py',
'release_tools/test_public_model_cards.py',
'release_tools/test_pressure_field_export.py',
'release_tools/verify_pressure_field_export.py',
'RELEASE_NOTES_TRACKFORMER_1_2.md',
'release_tools/build_release_benchmark.py',
'release_tools/plot_release_pressure_benchmark.py',
'release_tools/plot_daily_storm_final.py',
'release_tools/plot_model_announcement.py',
'release_tools/build_deepmind_period_comparison.py',
'release_tools/test_deepmind_period_comparison.py',
'release_tools/import_deepmind_release_results.py',
'release_tools/test_deepmind_release_results.py',
'release_tools/build_mangkhut_gif.py',
'release_tools/deepmind_daily_benchmark.py',
'release_tools/test_deepmind_daily_benchmark.py',
'docs/daily_storm_benchmark.md',
'docs/intensity_benchmark.md',
'docs/trackformer_1_2_evaluation.md',
'docs/trackformer_1_2_training_data.md',
'evaluation/training_data/trackformer_1_2_provenance.json',
'release_tools/audit_training_data.py',
'docs/deepmind_daily_benchmark.md',
'docs/showcase_archive.md',
'evaluation/README.md',
'docs/trackformer_1_2_architecture.svg',
'docs/trackformer_1_2_mangkhut.gif',
'docs/trackformer_1_2_mangkhut.gif.json',
'evaluation/daily_storm_final.json',
'evaluation/released_daily/released_daily_benchmark.json',
'evaluation/released_daily/released_daily_verification.json',
'evaluation/intensity/intensity_final.json',
'evaluation/intensity/verification.json',
'evaluation/trackformer_1_2_vs_1_1_270_storms_bars.png',
'evaluation/released_daily/pressure_comparison.png',
'evaluation/released_daily/model_1_2_benchmark.png',
'evaluation/released_daily/model_1_2_benchmark.json',
'evaluation/released_daily/model_1_2_after_2024_benchmark.png',
'evaluation/released_daily/model_1_2_after_2024_benchmark.json',
'evaluation/released_daily/model_1_2_before_2024_benchmark.png',
'evaluation/released_daily/model_1_2_before_2024_benchmark.json',
'evaluation/deepmind_daily/benchmark.json',
'evaluation/deepmind_daily/verification.json',
'evaluation/deepmind_daily/publication_audit.json',
'evaluation/deepmind_daily/protocol.json',
'evaluation/deepmind_daily/case-manifest.json',
'evaluation/deepmind_daily/canary.json',
'evaluation/deepmind_daily/period_comparison.json',
)
def sha(path):
with Path(path).open('rb') as stream:
return hashlib.file_digest(stream, 'sha256').hexdigest()
def media_url(stem, poster=False):
path = ('evaluation/trackformer_1_2_' + stem + '_video_poster.png'
if poster else 'docs/trackformer_1_2_' + stem + '.mp4')
return HF + '/resolve/' + MEDIA_REVISION + '/' + path
def player(stem, title):
return ('')
def render_card(original, github, figure_revision='main'):
metadata = re.match(r'\A---\n.*?\n---\n', original, re.S)
if not metadata:
raise ValueError('Preserve existing HF YAML metadata; missing header')
if github.count('## See the forecast: Mangkhut (2018)\n') != 1:
raise ValueError('Missing or ambiguous featured-film section')
card = github
for stem, alt in (('mangkhut', 'Trackformer 1.2 Mangkhut pressure and route forecast'),):
old = '[](' + media_url(stem) + ')'
if card.count(old) != 1:
raise ValueError('Missing or ambiguous primary preview: ' + stem)
card = card.replace(old, player(stem, alt), 1)
# Relative GitHub links need HF-specific URLs. Keep evolving documentation
# on main; pin unchanged scientific image bytes to the verified asset commit.
def link(match):
image, label, url = match.groups()
if url.startswith(('https:', 'http:', '#', 'mailto:')):
return match.group(0)
path, _, fragment = url.partition('#')
resolved = (ROOT / path).resolve()
if not resolved.is_relative_to(ROOT) or not resolved.exists():
raise ValueError('Invalid or missing relative public link: ' + path)
revision = figure_revision if path in CURRENT_FIGURES else MEDIA_REVISION
kind = 'resolve/' + revision if image else ('tree/main' if resolved.is_dir() else 'blob/main')
target = HF + '/' + kind + '/' + path + ('#' + fragment if fragment else '')
return image + '[' + label + '](' + target + ')'
card = re.sub(r'(!?)\[([^\[\]\n]*)\]\(([^)\s]+)\)', link, card)
card = metadata.group(0) + '\n' + card
if card.count('