Corriger la valeur par défaut de BLOG_RSS_URL
121
Configuration.md
121
Configuration.md
@@ -1,121 +0,0 @@
|
|||||||
# 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.
|
|
||||||
|
|
||||||
## 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 | (ex: `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.
|
|
||||||
143
unnamed.md
143
unnamed.md
@@ -1,50 +1,121 @@
|
|||||||
# Architecture
|
# Configuration
|
||||||
|
|
||||||
## Vue d'ensemble
|
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.
|
||||||
|
|
||||||
`pronote-sync` est un pipeline qui synchronise les données de **Pronote** vers **CalDAV** (agendas) et **XMPP** (notifications). Le flux principal est : **Pronote (iCal/pronotepy) → normalisation → comparaison avec l'agenda théorique → synchronisation CalDAV → synthèse IA (optionnelle) → notification XMPP**. Les sources sont **iCal** (primaire) et `pronotepy` (repli), avec trois modes de source : `auto`, `ical` et `pronotepy`.
|
## Principe
|
||||||
|
|
||||||
## Pipeline
|
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`).
|
||||||
|
|
||||||
1. Récupération Pronote — agenda et devoirs via iCal ou `pronotepy` ; messages et informations via `pronotepy` uniquement
|
## Variables Pronote
|
||||||
1. Normalisation et parsing — parsing iCal → modèles Pydantic, déduplication, normalisation des UID
|
|
||||||
1. Récupération du blog (RSS) — `feedparser`, déduplication par GUID, cache HTTP
|
|
||||||
1. Comparaison avec l'agenda théorique — matching déterministe, détection des changements
|
|
||||||
1. Synchronisation CalDAV — sync différentielle et idempotente, UID stables, conservation des annulés
|
|
||||||
1. Synthèse IA (optionnelle) — synthèse des changements, mode dégradé si échec
|
|
||||||
1. Envoi XMPP — message structuré (synthèse + devoirs bruts)
|
|
||||||
|
|
||||||
## Modules
|
| 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"] |
|
||||||
|
|
||||||
```text
|
> **Note** : `PRONOTE_URL` et `PRONOTE_ICAL_URL` sont deux contrats distincts. L'un ne doit **jamais** être déduit de l'autre.
|
||||||
pronote_sync/
|
|
||||||
├── config/ Configuration (Pydantic Settings)
|
## Variables CalDAV
|
||||||
├── models/ Modèles de données (Pydantic v2)
|
|
||||||
├── sources/ Connecteurs (Pronote iCal/pronotepy, blog RSS, agenda théorique)
|
| Variable | Description | Valeur par défaut | Type |
|
||||||
├── sync/ Synchronisation CalDAV et comparaison
|
|----------|-------------|--------------------|------|
|
||||||
├── synthesis/ Synthèse IA (OpenAI, litellm, openai-compatible)
|
| `CALDAV_URL` | URL du serveur CalDAV | obligatoire | SecretStr |
|
||||||
├── channels/ Canaux de sortie (XMPP)
|
| `CALDAV_USERNAME` | Identifiant CalDAV | obligatoire | str |
|
||||||
├── pipeline/ Orchestration (composition root, PipelineRunner)
|
| `CALDAV_PASSWORD` | Mot de passe CalDAV | obligatoire | SecretStr |
|
||||||
├── utils/ Utilitaires (redaction, logging, UID)
|
| `CALDAV_CALENDAR_PATH` | Chemin du calendrier sur le serveur | `/pronote-sync/` | str |
|
||||||
└── cli/ Interface en ligne de commande
|
| `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
|
||||||
```
|
```
|
||||||
|
|
||||||
## Injection de dépendances
|
## Variables Blog
|
||||||
|
|
||||||
Le projet utilise `typing.Protocol` et une **composition root** dans `pipeline/run.py`. Aucun singleton global n'est autorisé. Le `PipelineRunner` reçoit toutes ses dépendances via **injection par constructeur** : `PronoteFetcher`, `CalDAVClient`, `AgendaComparator`, `SynthesisProvider`, `Channel`.
|
| 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 |
|
||||||
|
|
||||||
## Sources de données
|
## Divers
|
||||||
|
|
||||||
Les modes de source sont les suivants :
|
| Variable | Description | Valeur par défaut | Type |
|
||||||
|
|----------|-------------|--------------------|------|
|
||||||
|
| `DRY_RUN` | Mode simulation (pas d'écriture) | `false` | bool |
|
||||||
|
| `LOG_LEVEL` | Niveau de log | `INFO` | str |
|
||||||
|
|
||||||
- `auto` : essaie d'abord iCal, puis bascule vers `pronotepy` **uniquement** si iCal lève une exception.
|
## Fichier .env
|
||||||
- `ical` : utilise **uniquement** iCal, sans bascule silencieuse.
|
|
||||||
- `pronotepy` : utilise **uniquement** `pronotepy`, sans bascule silencieuse.
|
|
||||||
- En mode `auto`, si iCal **et** `pronotepy` échouent → erreur critique explicite.
|
|
||||||
- Une liste vide est un **succès valide**, pas une panne.
|
|
||||||
- `PRONOTE_URL` (connexion API) et `PRONOTE_ICAL_URL` (flux iCal) sont deux paramètres **distincts**.
|
|
||||||
- Les messages ne sont disponibles que via `pronotepy` (absents du flux iCal).
|
|
||||||
|
|
||||||
## Flux de données
|
Pour créer votre fichier de configuration :
|
||||||
|
|
||||||
Le flux de données suit ce chemin : données brutes (iCal/`pronotepy`) → modèles Pydantic (`Lesson`, `Homework`, `Message`, etc.) → `PronoteData` (agrégé) → `AgendaDiff` (comparaison) → `CalDavSyncResult` → `SynthesisInput`/`SynthesisResult` → `XmppMessage` → envoi via le canal XMPP.
|
```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.
|
||||||
Reference in New Issue
Block a user