From 2730c4820dab3a9c221fb769e23086e20278cca7 Mon Sep 17 00:00:00 2001 From: Antoine Van Elstraete Date: Tue, 8 Sep 2026 19:15:06 +0200 Subject: [PATCH] Enrichir la section Pronote avec un guide pratique de configuration --- Configuration.md | 252 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 Configuration.md diff --git a/Configuration.md b/Configuration.md new file mode 100644 index 0000000..1a69880 --- /dev/null +++ b/Configuration.md @@ -0,0 +1,252 @@ +# Configuration + +Configuration via `pydantic-settings` depuis les variables d'environnement ou un fichier `.env`. Copiez `.env.example` vers `.env` pour démarrer. Les secrets utilisent `SecretStr` et sont masqués dans les logs. + +## Principe + +Les paramètres sont chargés automatiquement depuis les variables d'environnement ou un fichier `.env` à la racine du projet. Le fichier `.env` n'est **jamais** versionné (couvert par `.gitignore`). + +## Variables Pronote + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `PRONOTE_ICAL_URL` | URL du flux iCal Pronote (contient `icalsecurise`) | obligatoire si source `ical` | SecretStr | +| `PRONOTE_URL` | URL de la page Pronote pour `pronotepy` | obligatoire si source `pronotepy` | str | +| `PRONOTE_ACCOUNT_TYPE` | Type de compte Pronote | `parent` | str | +| `PRONOTE_USERNAME` | Identifiant Pronote | obligatoire si source `pronotepy` | str | +| `PRONOTE_PASSWORD` | Mot de passe Pronote | obligatoire si source `pronotepy` | SecretStr | +| `PRONOTE_ENT` | Slug ENT (résolu vers `pronotepy.ent`) | optionnel | str | +| `PRONOTE_AGENDA_SOURCE` | Source pour l'agenda | `auto` | Literal["auto", "ical", "pronotepy"] | +| `PRONOTE_HOMEWORK_SOURCE` | Source pour les devoirs | `auto` | Literal["auto", "ical", "pronotepy"] | +| `PRONOTE_MESSAGES_SOURCE` | Source pour les messages | `pronotepy` | Literal["pronotepy"] | + +> **Note** : `PRONOTE_URL` et `PRONOTE_ICAL_URL` sont deux contrats distincts. L'un ne doit **jamais** être déduit de l'autre. + +### Obtenir l'URL iCal (`PRONOTE_ICAL_URL`) + +L'URL iCal est le flux d'export du calendrier Pronote, contenant un token `icalsecurise`. Pour l'obtenir depuis l'espace parent Pronote : + +1. Se connecter à l'espace parent Pronote. +2. Aller dans la vue **Emploi du temps** (souvent sous *Vie scolaire* ou via le widget calendrier). +3. Chercher l'icône d'export agenda / synchronisation calendrier (souvent en haut à droite de l'emploi du temps, libellée « Exporter » ou « Synchroniser avec un agenda »). +4. Une fenêtre modale affiche l'URL d'abonnement iCal. + +Format attendu : + +``` +https://.index-education.net/pronote/ical/Edt_Prenom.ics?icalsecurise=&version=2024 +``` + +> ⚠️ Le token `icalsecurise` est sensible — le traiter comme un mot de passe. Cette URL est stockée en `SecretStr` et masquée dans les logs. + +> **Attention** : Certaines instances Pronote ne proposent pas d'export iCal. Si la page d'agenda ne montre que les options « Personnaliser » et « Générer un PDF pour impression », l'iCal n'est pas disponible. Dans ce cas, laisser `PRONOTE_ICAL_URL` vide et utiliser `pronotepy` comme source unique (voir [Exemple sans iCal](#exemple-sans-ical-pronotepy-uniquement) ci-dessous). + +### Obtenir l'URL de connexion (`PRONOTE_URL`) + +C'est l'URL de la page Pronote utilisée par `pronotepy` pour la connexion API. C'est l'URL visible dans le navigateur sur la page de connexion Pronote, **sans paramètres de requête**. + +Format : + +``` +https://.index-education.net/pronote/parent.html +``` + +> **Retirer tout paramètre de query string** (ex. `?identifiant=...`). `pronotepy` ne supporte pas les paramètres de requête dans cette URL. + +> `PRONOTE_URL` et `PRONOTE_ICAL_URL` sont deux contrats distincts : l'un ne doit jamais être déduit de l'autre. + +### Type de compte (`PRONOTE_ACCOUNT_TYPE`) + +Valeur par défaut : `parent`. Le projet utilise `pronotepy.ParentClient` pour un compte parent, `pronotepy.Client` pour un compte élève. Pour un compte parent, laisser la valeur par défaut. + +### Identifiants (`PRONOTE_USERNAME` et `PRONOTE_PASSWORD`) + +Identifiant et mot de passe de connexion à l'espace parent Pronote. Le mot de passe est stocké en `SecretStr` et masqué dans les logs et les erreurs. + +### ENT (`PRONOTE_ENT`) + +Si le collège passe par un ENT (Espace Numérique de Travail) pour la connexion à Pronote, renseigner le slug correspondant. Le projet résout ce slug vers une fonction de `pronotepy.ent` via une liste fermée. Si la connexion est directe (pas de redirection ENT), laisser `PRONOTE_ENT` vide ou absent. + +Liste des slugs ENT supportés : + +| Slug | ENT | +|------|-----| +| `monbureaunumerique` | Mon Bureau Numérique | +| `ent_elyco` | ENT Elyco | +| `bordeaux` | ENT Bordeaux | +| `ent_creuse` | ENT Creuse | +| `occitanie_montpellier` | Occitanie Montpellier | +| `paris_classe_numerique` | Paris Classe Numérique | +| `ile_de_france` | Île-de-France | +| `ent_hdf` | ENT Hauts-de-France | +| `ac_orleans_tours` | Académie Orléans-Tours | +| `ac_poitiers` | Académie Poitiers | +| `ac_rennes` | Académie Rennes | +| `laclasse_educonnect` | LaClasse (EduConnect) | +| `ent77` | ENT 77 | +| `ent_ecollege78` | eCollège 78 | +| `ent_essonne` | ENT Essonne | +| `val_doise` | Val d'Oise | +| `val_de_marne` | Val de Marne | +| `ent_var` | ENT Var | +| `atrium_sud` | Atrium Sud | +| `laclasse_lyon` | LaClasse Lyon | +| `eclat_bfc` | ÉCLAT Bourgogne-Franche-Comté | +| `cas_arsene76` | CAS Arsène 76 | +| `cas_ent27` | CAS ENT 27 | +| `cas_kosmos` | CAS Kosmos | +| `ent_creuse_educonnect` | ENT Creuse (EduConnect) | +| `ent_mayotte` | ENT Mayotte | +| `ent_somme` | ENT Somme | +| `ent_94` | ENT 94 | +| `extranet_colleges_somme` | Extranet Collèges Somme | +| `ac_reunion` | Académie Réunion | + +### Choix des sources (`PRONOTE_AGENDA_SOURCE`, `PRONOTE_HOMEWORK_SOURCE`, `PRONOTE_MESSAGES_SOURCE`) + +- `auto` (par défaut) : essaie d'abord iCal, puis bascule vers `pronotepy` uniquement si iCal lève une exception. +- `ical` : utilise uniquement iCal, sans bascule silencieuse. Requiert `PRONOTE_ICAL_URL`. +- `pronotepy` : utilise uniquement `pronotepy`, sans bascule silencieuse. Requiert `PRONOTE_URL`, `PRONOTE_USERNAME`, `PRONOTE_PASSWORD`, et `PRONOTE_ENT` (si applicable). +- En mode `auto`, si iCal et `pronotepy` échouent → erreur critique explicite. +- Une liste vide est un succès valide, pas une panne. +- Les messages ne sont disponibles que via `pronotepy` (absents du flux iCal). `PRONOTE_MESSAGES_SOURCE` est toujours `pronotepy`. + +### Exemple sans iCal (pronotepy uniquement) + +Quand l'instance Pronote ne propose pas d'export iCal : + +```ini +PRONOTE_URL=https://0640036s.index-education.net/pronote/parent.html +PRONOTE_ACCOUNT_TYPE=parent +PRONOTE_USERNAME=parent.dupont +PRONOTE_PASSWORD=ton_mot_de_passe + +# Pas d'ENT (connexion directe) +# PRONOTE_ENT à laisser vide ou absent + +# Sources : pronotepy uniquement (pas de repli iCal) +PRONOTE_AGENDA_SOURCE=pronotepy +PRONOTE_HOMEWORK_SOURCE=pronotepy +PRONOTE_MESSAGES_SOURCE=pronotepy +``` + +### Exemple avec iCal et pronotepy (mode auto) + +```ini +PRONOTE_ICAL_URL=https://.index-education.net/pronote/ical/Edt_Prenom.ics?icalsecurise=&version=2024 +PRONOTE_URL=https://.index-education.net/pronote/parent.html +PRONOTE_ACCOUNT_TYPE=parent +PRONOTE_USERNAME=parent.dupont +PRONOTE_PASSWORD=ton_mot_de_passe +PRONOTE_ENT=bordeaux + +PRONOTE_AGENDA_SOURCE=auto +PRONOTE_HOMEWORK_SOURCE=auto +PRONOTE_MESSAGES_SOURCE=pronotepy +``` + +### Tester la configuration + +```bash +pronote-sync --dry-run --log-level DEBUG +``` + +Le mode `--dry-run` valide la connexion et le pipeline sans écrire dans CalDAV/XMPP. Le `DEBUG` affiche les étapes détaillées. + +## Variables CalDAV + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `CALDAV_URL` | URL du serveur CalDAV | obligatoire | SecretStr | +| `CALDAV_USERNAME` | Identifiant CalDAV | obligatoire | str | +| `CALDAV_PASSWORD` | Mot de passe CalDAV | obligatoire | SecretStr | +| `CALDAV_CALENDAR_PATH` | Chemin du calendrier sur le serveur | `/pronote-sync/` | str | +| `CALDAV_ALLOW_INSECURE_HTTP` | Autoriser HTTP non sécurisé (localhost uniquement) | `false` | bool | + +## Fenêtre de synchronisation + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `SYNC_PAST_DAYS` | Nombre de jours dans le passé à synchroniser | `7` | int | +| `SYNC_FUTURE_DAYS` | Nombre de jours dans le futur à synchroniser | `30` | int | + +## Agenda théorique + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `THEORETICAL_AGENDA_PATH` | Chemin vers le fichier JSON de l'agenda théorique | `None` | str \| None | +| `SCHOOL_HOLIDAYS_PATH` | Chemin vers le fichier JSON des vacances scolaires | `None` | str \| None | +| `THEORETICAL_WEEK_ANCHOR_DATE` | Date de référence pour la parité des semaines | `None` | date \| None | +| `THEORETICAL_WEEK_ANCHOR_TYPE` | Parité de la semaine de référence | `None` | Literal["even", "odd"] \| None | + +## Variables XMPP + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `XMPP_ENABLED` | Activer la notification XMPP | `false` | bool | +| `XMPP_JID` | Identifiant XMPP (ex: `user@example.com`) | obligatoire si activé | str | +| `XMPP_PASSWORD` | Mot de passe XMPP | obligatoire si activé | SecretStr | +| `XMPP_HOST` | Hôte XMPP | `""` | str | +| `XMPP_PORT` | Port XMPP | `5222` | int | +| `XMPP_TO` | Destinataire XMPP | obligatoire si activé | str | +| `XMPP_RESOURCE` | Ressource XMPP | `pronote-sync` | str | +| `XMPP_USE_TLS` | Utiliser TLS pour la connexion | `true` | bool | +| `XMPP_TIMEOUT` | Délai d'attente en secondes | `30` | int | + +## Variables IA + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `AI_ENABLED` | Activer la synthèse IA | `false` | bool | +| `AI_PROVIDER` | Fournisseur IA | `openai` | Literal["openai", "litellm", "openai-compatible"] | +| `AI_BASE_URL` | URL de base de l'API IA | `None` | str \| None | +| `AI_API_KEY` | Clé API IA | `None` | SecretStr | +| `AI_MODEL` | Modèle IA | `None` | str \| None | +| `AI_ALLOW_INSECURE_HTTP` | Autoriser HTTP non sécurisé pour `openai-compatible` | `false` | bool | + +> **Note** : Le fournisseur `openai-compatible` réutilise `OpenAISynthesisProvider` avec un `base_url` personnalisé. `AI_BASE_URL` et `AI_MODEL` sont requis pour ce fournisseur. L'URL doit utiliser `https` sauf si `AI_ALLOW_INSECURE_HTTP=true`. Les identifiants dans l'URL sont rejetés. Les paramètres sensibles dans la *query string* sont rejetés. Aucune manipulation automatique de `/v1` n'est effectuée. En cas de configuration invalide, la factory retourne `None` avec un avertissement (mode dégradé). + +Exemples de configuration pour `openai-compatible` : + +```bash +# OpenRouter (HTTPS) +AI_PROVIDER=openai-compatible +AI_BASE_URL=https://openrouter.ai/api/v1 +AI_MODEL=fournisseur/modele +AI_API_KEY=your-openrouter-key +AI_ALLOW_INSECURE_HTTP=false + +# Ollama local (HTTP) +AI_PROVIDER=openai-compatible +AI_BASE_URL=http://127.0.0.1:11434/v1 +AI_MODEL=modele-local +AI_API_KEY=local-not-required +AI_ALLOW_INSECURE_HTTP=true +``` + +## Variables Blog + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `BLOG_ENABLED` | Activer la synchronisation du blog | `false` | bool | +| `BLOG_RSS_URL` | URL du flux RSS du blog | `https://blogpeda.ac-bordeaux.fr/cjeliote/?feed=rss2` | str | + +## Divers + +| Variable | Description | Valeur par défaut | Type | +|----------|-------------|--------------------|------| +| `DRY_RUN` | Mode simulation (pas d'écriture) | `false` | bool | +| `LOG_LEVEL` | Niveau de log | `INFO` | str | + +## Fichier .env + +Pour créer votre fichier de configuration : + +```bash +cp .env.example .env +# Éditer .env avec vos paramètres +``` + +> **Rappel** : Le fichier `.env` n'est **jamais** versionné. Utilisez `.env.example` comme modèle. + +Voir aussi : [Sécurité](Sécurité) pour la gestion des secrets, [Déploiement](Déploiement) pour la configuration en production. \ No newline at end of file