| """loader.py — le Space public, le code privé. |
| |
| Un Space public expose ses fichiers. Pour garder la méthode fermée tout en |
| laissant l'outil utilisable, ce fichier est le SEUL point d'entrée public : il |
| télécharge la charge utile depuis un dépôt Hugging Face **privé** au démarrage, |
| puis lance l'application. |
| |
| Ce qui reste PUBLIC, délibérément : |
| - ce chargeur, le Dockerfile, requirements.txt ; |
| - `falrun.py` — les 100 lignes qui manipulent la clé fal du visiteur. C'est |
| l'argument qui fait qu'on ose coller une clé ; le cacher coûterait plus que |
| ce qu'il protégerait (il ne contient aucun savoir-faire) ; |
| - les vidéos d'exemple et les poids publics (GNM de Google, MediaPipe). |
| |
| Ce qui part en PRIVÉ : tout ce qui encode la méthode — l'alignement |
| yeux-sur-yeux, le fondu de raccord, les compounds des presets, le scanner de |
| fenêtres, la calibration en boucle fermée, et le stage 3D. |
| |
| Configuration (Settings → Variables and secrets) : |
| PRIVATE_REPO = "<user>/retakes-core" (variable) |
| HF_TOKEN = un token avec accès LECTURE à ce dépôt (secret) |
| |
| Le token ne quitte jamais le conteneur : il n'est lu que par ce fichier, et la |
| page servie au visiteur ne contient que l'interface Gradio. |
| """ |
| from __future__ import annotations |
|
|
| import os |
| import runpy |
| import sys |
|
|
| APP_DIR = os.path.dirname(os.path.abspath(__file__)) |
| REPO = os.environ.get('PRIVATE_REPO', '').strip() |
| TOKEN = (os.environ.get('HF_TOKEN') or os.environ.get('HUGGINGFACE_TOKEN') or '').strip() |
| REVISION = os.environ.get('PRIVATE_REVISION', 'main').strip() or 'main' |
|
|
|
|
| def _placeholder(title: str, body: str) -> None: |
| """Un Space mal configuré doit l'ANNONCER, pas mourir sur une trace de pile. |
| |
| Sinon le visiteur voit « Runtime error » et le propriétaire cherche dans les |
| logs de build alors que le problème est un secret manquant. |
| """ |
| import gradio as gr |
| with gr.Blocks(title='Retakes — configuration') as demo: |
| gr.Markdown(f'# {title}\n\n{body}') |
| demo.launch(server_name='0.0.0.0', server_port=7860) |
| sys.exit(0) |
|
|
|
|
| def main() -> None: |
| app = os.path.join(APP_DIR, 'app.py') |
| |
| |
| |
| |
| if os.path.exists(app): |
| sys.path.insert(0, APP_DIR) |
| runpy.run_path(app, run_name='__main__') |
| return |
|
|
| if not REPO or not TOKEN: |
| missing = ' et '.join( |
| x for x in (('`PRIVATE_REPO` (variable)' if not REPO else ''), |
| ('`HF_TOKEN` (secret)' if not TOKEN else '')) if x) |
| _placeholder( |
| '⚙️ Configuration incomplète', |
| f'Ce Space charge son code depuis un dépôt privé. Il manque {missing} ' |
| 'dans *Settings → Variables and secrets*.\n\nAucune donnée visiteur ' |
| "n'est concernée : l'application n'a pas démarré.") |
|
|
| from huggingface_hub import HfApi, snapshot_download |
|
|
| |
| |
| |
| |
| |
| try: |
| HfApi().repo_info(repo_id=REPO, repo_type='model', token=TOKEN) |
| except Exception as e: |
| name = type(e).__name__ |
| denied = 'RepositoryNotFound' in name or 'GatedRepo' in name or '401' in str(e)[:80] |
| _placeholder( |
| '⚙️ Le code privé est inaccessible', |
| (f'Le Space ne peut pas lire `{REPO}`.\n\n' |
| '**Cause la plus fréquente** : un token *fine-grained* qui ne liste pas ' |
| 'ce dépôt. Il faut lui cocher explicitement l\'accès en **lecture** à ' |
| 'ce dépôt précis — ou utiliser un token *classic* avec la portée ' |
| '`read`.\n\nVérifie aussi que `PRIVATE_REPO` est exact.' |
| if denied else |
| f'Erreur `{name}`. Vérifie `PRIVATE_REPO` et le token dans ' |
| '*Settings → Variables and secrets*.') |
| + '\n\nAucune donnée visiteur n\'est concernée : l\'application n\'a ' |
| 'pas démarré.') |
|
|
| try: |
| |
| |
| |
| |
| snapshot_download(repo_id=REPO, repo_type='model', revision=REVISION, |
| token=TOKEN, local_dir=APP_DIR) |
| except Exception as e: |
| |
| |
| _placeholder('⚙️ Téléchargement du code échoué', |
| f'`{type(e).__name__}`. Le dépôt est accessible mais le ' |
| 'téléchargement a échoué — réessaie en redémarrant le Space.') |
|
|
| if not os.path.exists(app): |
| _placeholder('⚙️ Charge utile incomplète', |
| f'`{REPO}` est lisible, mais ne contient pas `app.py` à sa ' |
| 'racine. Vérifie ce que `deploy_split.sh` y a poussé.') |
| sys.path.insert(0, APP_DIR) |
| runpy.run_path(app, run_name='__main__') |
|
|
|
|
| if __name__ == '__main__': |
| main() |
|
|