Public Access
fix: Résolution de l'import circulaire, ajout des boutons UI et étiquetage Gitea
Build and Push Docker Image / build-and-push (push) Successful in 33s
Build and Push Docker Image / build-and-push (push) Successful in 33s
This commit is contained in:
1 parent
b20ce7e903
commit
34163a630c
5 files changed
+363
-29
No files matched your search
@@ -6111,3 +6111,326 @@ git push origin main
|
|||||||
Allez observer l'onglet "Actions" sur Gitea. Le conteneur devrait maintenant s'authentifier avec succès et construire l'image ! Le processus complet de compilation (Build and push Docker image) peut prendre entre 2 et 5 minutes la première fois.
|
Allez observer l'onglet "Actions" sur Gitea. Le conteneur devrait maintenant s'authentifier avec succès et construire l'image ! Le processus complet de compilation (Build and push Docker image) peut prendre entre 2 et 5 minutes la première fois.
|
||||||
|
|
||||||
Le log passe-t-il enfin au vert de votre côté ?
|
Le log passe-t-il enfin au vert de votre côté ?
|
||||||
|
Ah ! L'erreur sur votre capture d'écran ("Veuillez respecter le format requis") est un grand classique des systèmes CI/CD.
|
||||||
|
|
||||||
|
L'explication est simple : Gitea Actions (tout comme GitHub Actions dont il s'inspire) interdit de créer des secrets personnalisés dont le nom commence par GITEA_ (ou GITHUB_). Ce préfixe est strictement réservé aux variables internes du système, d'où le blocage de l'interface.
|
||||||
|
|
||||||
|
Voici comment contourner cette restriction de nommage en deux minutes.
|
||||||
|
|
||||||
|
1. Renommer les secrets dans l'interface Gitea
|
||||||
|
Sur la page d'ajout de secret que vous avez ouverte, utilisez simplement des noms génériques sans le préfixe interdit :
|
||||||
|
|
||||||
|
Nom : REGISTRY_USERNAME (Valeur : xavier)
|
||||||
|
|
||||||
|
Nom : REGISTRY_TOKEN (Valeur : votre jeton d'accès)
|
||||||
|
|
||||||
|
2. Mettre à jour le fichier Workflow
|
||||||
|
Puisque nous avons changé le nom des secrets, il faut indiquer ces nouveaux noms à notre script d'automatisation.
|
||||||
|
|
||||||
|
Modifiez le fichier .gitea/workflows/docker-build.yml sur votre PC pour qu'il ressemble exactement à ceci :
|
||||||
|
|
||||||
|
YAML
|
||||||
|
name: Build and Push Docker Image
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Log in to Gitea Container Registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: gitea.aethas38.duckdns.org
|
||||||
|
# On utilise ici les nouveaux noms autorisés
|
||||||
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: gitea.aethas38.duckdns.org/xavier/aethas-free:latest
|
||||||
|
3. Relancer la génération
|
||||||
|
Une fois le fichier .yml modifié avec les bons noms de secrets, exécutez ces commandes dans votre terminal pour pousser la correction et déclencher le runner :
|
||||||
|
|
||||||
|
Bash
|
||||||
|
git add .
|
||||||
|
git commit -m "fix: Renommage des secrets pour contourner la restriction Gitea"
|
||||||
|
git push origin main
|
||||||
|
ça me saoul
|
||||||
|
|
||||||
|
Je comprends parfaitement votre frustration. Configurer un pipeline d'intégration continue (CI/CD) de bout en bout est de loin la partie la plus ingrate et capricieuse d'un projet de développement, car la moindre case non cochée du côté du serveur rejette tout le processus.
|
||||||
|
|
||||||
|
Voici la bonne nouvelle tirée de vos logs : la correction des noms de variables a fonctionné. Vos secrets sont désormais parfaitement lus et transmis au Runner (ils s'affichent sous la forme *** dans le journal).
|
||||||
|
TXT
|
||||||
|
|
||||||
|
L'échec à l'étape Log in to Gitea Container Registry est maintenant dû à un rejet strict de Gitea lors de la tentative de connexion. Cela s'explique généralement par l'une de ces deux raisons :
|
||||||
|
TXT
|
||||||
|
|
||||||
|
Le jeton (REGISTRY_TOKEN) que vous avez généré ne possède pas l'autorisation explicite write:package (Écrire des paquets) requise par Gitea.
|
||||||
|
|
||||||
|
La fonctionnalité "Registre de paquets" (Packages) n'est pas activée au niveau du fichier app.ini de votre serveur Gitea.
|
||||||
|
|
||||||
|
La Solution Anti-Prise de Tête : Le "Build" Local via Dockge
|
||||||
|
Puisque cette étape vous bloque et vous empêche de tester le code Python que nous avons préparé, je vous propose d'arrêter de vous battre avec le registre distant de Gitea.
|
||||||
|
|
||||||
|
Vous utilisez déjà Dockge sur votre serveur, ce qui est une excellente chose. Nous pouvons demander à Dockge de compiler l'image Docker directement sur la machine hôte à partir du dossier app-code qu'il met à jour, sans jamais avoir besoin de s'authentifier sur un registre de paquets externe.
|
||||||
|
|
||||||
|
Étape 1 : Mettre en pause Gitea Actions
|
||||||
|
|
||||||
|
Sur votre PC, supprimez simplement le dossier .gitea (et son fichier .yml à l'intérieur) de votre projet.
|
||||||
|
|
||||||
|
Faites un commit : git add ., git commit -m "Désactivation temporaire de Gitea Actions", git push origin main.
|
||||||
|
|
||||||
|
Étape 2 : Modifier votre Stack dans Dockge
|
||||||
|
|
||||||
|
Allez sur l'interface web de votre Dockge, ouvrez la stack AETHAS38_MULTI_IA et remplacez la ligne image: ... par build: ./app-code.
|
||||||
|
|
||||||
|
Votre docker-compose.yml ressemblera exactement à ceci :
|
||||||
|
|
||||||
|
YAML
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
aethas38_app:
|
||||||
|
container_name: aethas38_app
|
||||||
|
build: ./app-code
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5005:5001"
|
||||||
|
volumes:
|
||||||
|
- /DATA/AppData/MULTI-IA-AETHAS38:/app/data
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Paris
|
||||||
|
Étape 3 : Relancer via votre script de mise à jour
|
||||||
|
|
||||||
|
Connectez-vous en SSH à votre serveur et exécutez le script que nous avions créé :
|
||||||
|
|
||||||
|
Bash
|
||||||
|
sudo /opt/stacks/AETHAS38_MULTI_IA/update_aethas.sh
|
||||||
|
Ce script va faire un git pull pour récupérer vos derniers fichiers Python, puis Dockge va recompiler l'image localement et lancer le conteneur.
|
||||||
|
|
||||||
|
Voulez-vous appliquer cette méthode locale beaucoup plus simple pour débloquer la situation et pouvoir enfin nous concentrer sur le code du module financier ?
|
||||||
|
je suis têtu comme un ane
|
||||||
|
|
||||||
|
C'est une excellente qualité en développement ! Et votre intuition sur la différence entre le token d'exécution et le token de registre est parfaitement exacte. Le fait de persévérer sur l'automatisation Gitea maintenant nous fera gagner un temps précieux par la suite.
|
||||||
|
|
||||||
|
Analysons vos actions et la solution :
|
||||||
|
|
||||||
|
Vous avez raison, l'onglet "Exécuteurs" (Runners) fournit un token d'enregistrement pour l'agent (act_runner). Ce token sert uniquement à relier votre serveur à Gitea.
|
||||||
|
En revanche, le REGISTRY_TOKEN que Gitea réclame à l'étape Log in to Gitea Container Registry est un Jeton d'accès personnel (Personal Access Token - PAT). C'est ce jeton qui donne le droit d'écrire dans la section "Packages" de votre compte.
|
||||||
|
TXT
|
||||||
|
+ 1
|
||||||
|
|
||||||
|
Voici la procédure exacte pour corriger ce point et valider enfin ce build.
|
||||||
|
|
||||||
|
1. Générer le bon Jeton (REGISTRY_TOKEN)
|
||||||
|
Vous n'avez pas besoin de couper le docker Gitea. Restez simplement sur l'interface web de Gitea :
|
||||||
|
|
||||||
|
Cliquez sur votre photo de profil en haut à droite > Paramètres (Settings).
|
||||||
|
|
||||||
|
Dans le menu de gauche, allez dans Applications.
|
||||||
|
|
||||||
|
Dans la section Générer un nouveau jeton, entrez un nom (ex: Aethas-Registry-Push).
|
||||||
|
|
||||||
|
Dans les cases à cocher en dessous, vous devez absolument cocher les permissions suivantes :
|
||||||
|
|
||||||
|
write:package (C'est la permission vitale pour pousser l'image Docker).
|
||||||
|
|
||||||
|
read:user (Souvent requis pour l'authentification).
|
||||||
|
|
||||||
|
Cliquez sur Générer le jeton et copiez la longue chaîne qui s'affiche (elle ne sera plus jamais visible).
|
||||||
|
|
||||||
|
2. Mettre à jour les Secrets
|
||||||
|
Retournez dans les Paramètres de votre dépôt > Actions > Secrets (Là où vous avez pris la capture d'écran).
|
||||||
|
TXT
|
||||||
|
|
||||||
|
Supprimez l'ancien REGISTRY_TOKEN (l'icône poubelle à droite).
|
||||||
|
|
||||||
|
Recréez le secret REGISTRY_TOKEN en y collant le nouveau jeton généré à l'étape précédente.
|
||||||
|
|
||||||
|
Laissez le REGISTRY_USERNAME intact (il doit contenir xavier).
|
||||||
|
|
||||||
|
3. Lancer le Test Définitif
|
||||||
|
Puisque nous avons mis à jour la configuration côté Gitea, il faut déclencher un nouveau "push" pour que le runner essaie de s'authentifier avec ce nouveau jeton.
|
||||||
|
|
||||||
|
Dans votre terminal local (sur votre PC) :
|
||||||
|
|
||||||
|
Bash
|
||||||
|
git commit -m "chore: Test du nouveau jeton d'accès aux paquets (PAT)" --allow-empty
|
||||||
|
git push origin main
|
||||||
|
Cette fois, l'étape "Log in to Gitea Container Registry" devrait se valider, et la compilation "Build and push Docker image" pourra commencer !
|
||||||
|
|
||||||
|
J'attends le verdict du log avec impatience.
|
||||||
|
on va y arriver on avance bien 😃
|
||||||
|
|
||||||
|
EDIT DE VOTRE QUESTION :
|
||||||
|
|
||||||
|
Le paquet est créé mais n'est pas visible directement dans le dépôt (clic sur la flèche rouge). Comment le rattacher (manuellement puis automatiquement) ? Il faut ensuite mettre à jour la stack sur Dockge, vérifier le script auto-update, et corriger la disparition des boutons PayPal/Dons sur le site.
|
||||||
|
|
||||||
|
C'est une immense victoire ! Votre ténacité a payé, le Runner Gitea fonctionne parfaitement et a réussi à compiler et pousser votre conteneur Docker en totale autonomie. C'est le cœur d'une infrastructure DevOps professionnelle qui vient de prendre vie ! 🚀
|
||||||
|
|
||||||
|
Voici comment régler les derniers détails pour que tout s'imbrique parfaitement.
|
||||||
|
|
||||||
|
1. Rattacher le Paquet au Dépôt (Gitea)
|
||||||
|
L'image de votre conteneur a bien été publiée sur votre compte utilisateur (comme on le voit sur votre capture de la page du paquet), mais Gitea ne sait pas d'emblée qu'elle "appartient" au dépôt aethas-free (d'où le message indiquant qu'il n'y a pas de paquet pour le moment).
|
||||||
|
TXT
|
||||||
|
+ 1
|
||||||
|
|
||||||
|
Action manuelle immédiate :
|
||||||
|
|
||||||
|
Sur la page de votre paquet fraîchement créé (celle de votre dernière capture), cherchez l'option "Lier le paquet à un dépôt" (souvent dans les paramètres du paquet ou directement sur sa page de présentation).
|
||||||
|
TXT
|
||||||
|
|
||||||
|
Sélectionnez votre dépôt aethas-free et validez. Il apparaîtra désormais dans l'onglet "Paquets" de votre dépôt !
|
||||||
|
|
||||||
|
Action pour l'automatiser à l'avenir :
|
||||||
|
Pour que Gitea fasse ce lien tout seul à chaque nouvelle mise à jour, nous devons ajouter une "étiquette" (Label) dans votre fichier Dockerfile.
|
||||||
|
|
||||||
|
👉 Veuillez me transmettre votre Dockerfile actuel pour que je vous ajoute la ligne d'automatisation.
|
||||||
|
|
||||||
|
2. Mettre à jour la Stack Dockge et le Script Auto-Update
|
||||||
|
Maintenant que l'image est sur le registre Gitea, votre serveur n'a plus besoin de compiler le code (la fameuse commande build: .). Il lui suffit de la télécharger.
|
||||||
|
|
||||||
|
Sur l'interface de Dockge :
|
||||||
|
Remplacez le contenu actuel de votre docker-compose.yml par celui-ci (vous noterez qu'on remplace build par image) :
|
||||||
|
|
||||||
|
YAML
|
||||||
|
services:
|
||||||
|
aethas38_app:
|
||||||
|
container_name: aethas38_app
|
||||||
|
image: gitea.aethas38.duckdns.org/xavier/aethas-free:latest
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5005:5001"
|
||||||
|
volumes:
|
||||||
|
- /DATA/AppData/MULTI-IA-AETHAS38:/app/data
|
||||||
|
environment:
|
||||||
|
- TZ=Europe/Paris
|
||||||
|
Cliquez sur Update puis Deploy. Le serveur va télécharger l'image depuis Gitea et lancer le site.
|
||||||
|
|
||||||
|
Vérification du Script Auto-Update :
|
||||||
|
Connectez-vous en SSH à votre serveur et lancez la commande manuellement pour simuler une mise à jour :
|
||||||
|
|
||||||
|
Bash
|
||||||
|
sudo /opt/stacks/AETHAS38_MULTI_IA/update_aethas.sh
|
||||||
|
Si le script s'exécute sans erreur, qu'il "pull" la nouvelle image et relance le conteneur, c'est que votre boucle complète d'intégration continue est 100% opérationnelle !
|
||||||
|
|
||||||
|
3. Résolution du problème des boutons PayPal / Dons
|
||||||
|
C'est un excellent point de vigilance. Si les modules de dons (et particulièrement celui gravé en dur dans le code pour respecter votre licence EULA) n'apparaissent plus, c'est probablement qu'ils ont été écrasés lors d'une précédente refonte de la barre latérale ou du fichier theme.py.
|
||||||
|
|
||||||
|
Pour corriger cela tout en respectant notre règle stricte (1 fonction = 1 module), je dois réintégrer ces éléments dans l'interface sans casser le reste.
|
||||||
|
|
||||||
|
👉 Veuillez me transmettre les fichiers suivants pour vérification et mise à jour :
|
||||||
|
|
||||||
|
modules/ui_components.py (C'est lui qui gère l'affichage de la barre latérale et des boutons).
|
||||||
|
|
||||||
|
README.md (Afin que j'incrémente la validation de l'étape CI/CD Gitea).
|
||||||
|
|
||||||
|
Dockerfile (Pour l'automatisation du rattachement Gitea vue au point 1).
|
||||||
|
|
||||||
|
J'attends vos fichiers pour vous fournir les correctifs finaux de cette étape décisive !
|
||||||
|
|
||||||
|
on va y arriver on avance bien 😃
|
||||||
|
ça me brise les burnes mais je lâche pas
|
||||||
|
|
||||||
|
EDIT DE VOTRE QUESTION :
|
||||||
|
|
||||||
|
Le paquet a été généré mais il boucle au redémarrage de la stack avec une erreur ImportError: cannot import name 'verifier_et_valider_budget' from 'modules.billing_manager'. J'ai transmis les fichiers Dockerfile, ui_components.py et README.md pour corriger cela, ajouter le lien Gitea dans le Dockerfile et rétablir les boutons de dons.
|
||||||
|
|
||||||
|
Votre ténacité est remarquable ! Et c'est exactement l'attitude qu'il faut pour venir à bout d'une configuration DevOps de zéro. Vous avez fait le plus dur en franchissant l'obstacle Gitea.
|
||||||
|
|
||||||
|
Analysons ces deux nouveaux points de friction :
|
||||||
|
|
||||||
|
L'erreur de la boucle (ImportError) : Cette erreur survient car nous n'avions pas encore finalisé ni déposé le module billing_manager.py (qui contient la fonction verifier_et_valider_budget) alors que nous avions déjà modifié chat_handler.py pour qu'il l'appelle. Le conteneur essaie d'importer une fonction qui n'existe pas encore dans ce fichier, d'où le crash immédiat.
|
||||||
|
TXT
|
||||||
|
|
||||||
|
L'avertissement Google GenAI (FutureWarning) : Google a décidé de déprécier (rendre obsolète) la librairie google-generativeai pour forcer le passage à google-genai (SDK >0.4). Ce n'est pas bloquant pour le moment (c'est un simple Warning), mais nous le corrigerons plus tard pour rester à jour.
|
||||||
|
TXT
|
||||||
|
+ 1
|
||||||
|
|
||||||
|
Voici le plan d'action immédiat pour tout remettre au vert.
|
||||||
|
|
||||||
|
1. Finalisation de la vue UI (Boutons Dons)
|
||||||
|
J'ai analysé ui_components.py. Le bouton PayPal est bien présent (render_paypal_donation_widget()), mais nous allons ajouter le deuxième bouton obligatoire imposé par votre EULA (le soutien au créateur) de manière inaltérable.
|
||||||
|
PY
|
||||||
|
+ 1
|
||||||
|
|
||||||
|
Action : Remplacez le bloc nav-buttons de votre fichier modules/ui_components.py par ce code :
|
||||||
|
|
||||||
|
Python
|
||||||
|
Div(
|
||||||
|
A("+ Nouvelle discussion", href="/new_chat", cls="new-chat-btn"),
|
||||||
|
A("💾 Exporter JSON", href="/export_json", target="_blank", cls="export-btn"),
|
||||||
|
# Module de don modifiable par l'hébergeur
|
||||||
|
render_paypal_donation_widget(),
|
||||||
|
# Module inaltérable (Licence EULA Aethas38)
|
||||||
|
A("❤️ Soutenir le créateur de ce projet", href="https://paypal.me/VotreLienXavier", target="_blank", style="margin-left: 10px; padding: 10px; background-color: #e2e8f0; color: #1a202c; border-radius: 5px; text-decoration: none; font-weight: bold; border: 1px solid #cbd5e0;"),
|
||||||
|
cls="nav-buttons"
|
||||||
|
),
|
||||||
|
(Pensez à insérer votre véritable lien PayPal à la place de VotreLienXavier).
|
||||||
|
|
||||||
|
2. Automatisation du lien Dépôt/Paquet (Gitea)
|
||||||
|
Pour que votre paquet se lie automatiquement au dépôt à chaque push (et n'affiche plus l'écran de votre capture), nous devons utiliser l'étiquette standard OCI (Open Container Initiative) dans votre Dockerfile.
|
||||||
|
TXT
|
||||||
|
|
||||||
|
Action : Modifiez votre fichier Dockerfile à la racine en ajoutant la ligne LABEL :
|
||||||
|
Inconnu
|
||||||
|
|
||||||
|
Dockerfile
|
||||||
|
FROM python:3.13-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Ligne ajoutée pour lier l'image au dépôt Gitea automatiquement
|
||||||
|
LABEL org.opencontainers.image.source="https://gitea.aethas38.duckdns.org/xavier/aethas-free"
|
||||||
|
|
||||||
|
# Installation des dépendances système nécessaires pour certaines librairies Python
|
||||||
|
RUN apt-get update && apt-get install -y gcc default-libmysqlclient-dev && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copie des requirements et installation
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Copie du reste de l'application
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Exposition du port
|
||||||
|
EXPOSE 5001
|
||||||
|
|
||||||
|
# Lancement du serveur Uvicorn (FastHTML)
|
||||||
|
CMD ["python", "main.py"]
|
||||||
|
3. Mise en place du module manquant (Billing Manager)
|
||||||
|
Pour stopper l'erreur de boucle, vous devez impérativement créer le fichier modules/billing_manager.py (ou vérifier qu'il s'y trouve bien et contient la fonction avec la marge de 15%).
|
||||||
|
TXT
|
||||||
|
|
||||||
|
Action : Assurez-vous de créer le fichier modules/billing_manager.py avec le code exact que je vous avais fourni précédemment (celui qui contient def verifier_et_valider_budget(prompt, modele_id, utilisateur_vip=False):).
|
||||||
|
|
||||||
|
4. Incrémentation du README
|
||||||
|
Action : Remplacez la section Phase 5 de votre README.md pour refléter l'ajout de la sécurité UI et du TCD :
|
||||||
|
MD
|
||||||
|
|
||||||
|
Markdown
|
||||||
|
### Phase 5 : Sécurité Financière & Facturation 💰
|
||||||
|
<!-- MAJ 18/08/2026 : Intégration du module financier, calcul des marges et interface de validation -->
|
||||||
|
- [x] Pré-calcul local du nombre de tokens (via `tiktoken`) pour estimer le coût avant envoi.
|
||||||
|
- [x] Intégration du gestionnaire financier strict : simulation des coûts, blocage immédiat si le solde est insuffisant et gestion spécifique pour les utilisateurs VIP (Zéro marge/Zéro coût).
|
||||||
|
- [ ] Interface UI : Affichage du Pop-Up de validation du coût et affichage de la cagnotte utilisateur.
|
||||||
|
- [ ] Cryptage absolu des données sensibles bancaires.
|
||||||
|
- [ ] Module de conversion des devises en temps réel.
|
||||||
|
- [x] **Gestionnaire Financier :** Majoration automatique (15%) appliquée selon les statuts pour générer la facturation finale.
|
||||||
|
- [ ] Export comptable Excel (TCD) avec archivage PDF automatisé (Admin uniquement).
|
||||||
|
Prochaine étape
|
||||||
|
Exécutez vos commandes magiques pour valider cette étape et forcer la génération du paquet :
|
||||||
|
|
||||||
|
Bash
|
||||||
|
git add .
|
||||||
|
git commit -m "fix: Résolution de l'import circulaire, ajout des boutons UI et étiquetage Gitea"
|
||||||
|
git push origin main
|
||||||
|
Une fois le package recréé et téléchargé sur Dockge, le conteneur passera au vert ! Dites-moi dès que c'est bon.
|
||||||
|
|
||||||
|
ça me brise les burnes mais je lâche pas
|
||||||
@@ -2,6 +2,9 @@ FROM python:3.13-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Ligne ajoutée pour lier l'image au dépôt Gitea automatiquement
|
||||||
|
LABEL org.opencontainers.image.source="https://gitea.aethas38.duckdns.org/xavier/aethas-free"
|
||||||
|
|
||||||
# Installation des dépendances système nécessaires pour certaines librairies Python
|
# Installation des dépendances système nécessaires pour certaines librairies Python
|
||||||
RUN apt-get update && apt-get install -y gcc default-libmysqlclient-dev && rm -rf /var/lib/apt/lists/*
|
RUN apt-get update && apt-get install -y gcc default-libmysqlclient-dev && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ Pour fonctionner de manière optimale, l'Orchestrateur Local nécessite au minim
|
|||||||
- [ ] Multilinguisme : Adaptation automatique de la langue du site via IP.
|
- [ ] Multilinguisme : Adaptation automatique de la langue du site via IP.
|
||||||
|
|
||||||
### Phase 5 : Sécurité Financière & Facturation 💰
|
### Phase 5 : Sécurité Financière & Facturation 💰
|
||||||
<!-- MAJ : Validation du gestionnaire financier strict -->
|
<!-- MAJ 18/08/2026 : Intégration du module financier, calcul des marges et interface de validation -->
|
||||||
- [x] Pré-calcul local du nombre de tokens (via `tiktoken`) pour estimer le coût avant envoi.
|
- [x] Pré-calcul local du nombre de tokens (via `tiktoken`) pour estimer le coût avant envoi.
|
||||||
- [x] Intégration du gestionnaire financier strict : simulation des coûts, blocage immédiat si le solde est insuffisant et gestion spécifique pour les utilisateurs VIP (Zéro marge/Zéro coût).
|
- [x] Intégration du gestionnaire financier strict : simulation des coûts, blocage immédiat si le solde est insuffisant et gestion spécifique pour les utilisateurs VIP (Zéro marge/Zéro coût).
|
||||||
- [ ] Interface UI : Affichage du Pop-Up de validation du coût et affichage de la cagnotte utilisateur.
|
- [ ] Interface UI : Affichage du Pop-Up de validation du coût et affichage de la cagnotte utilisateur.
|
||||||
- [ ] Cryptage absolu des données sensibles bancaires.
|
- [ ] Cryptage absolu des données sensibles bancaires.
|
||||||
- [ ] Module de conversion des devises en temps réel.
|
- [ ] Module de conversion des devises en temps réel.
|
||||||
- [x] **Gestionnaire Financier :** Majoration automatique appliquée selon les statuts pour générer la facturation finale.
|
- [x] **Gestionnaire Financier :** Majoration automatique (15%) appliquée selon les statuts pour générer la facturation finale.
|
||||||
- [ ] Export comptable Excel (TCD) avec archivage PDF automatisé (Admin uniquement).
|
- [ ] Export comptable Excel (TCD) avec archivage PDF automatisé (Admin uniquement).
|
||||||
|
|
||||||
### Phase 6 : Nouvelles Capacités IA (Spécialisations & Modèles) 🤖
|
### Phase 6 : Nouvelles Capacités IA (Spécialisations & Modèles) 🤖
|
||||||
|
|||||||
+32
-27
@@ -1,47 +1,52 @@
|
|||||||
import os
|
|
||||||
import tiktoken
|
import tiktoken
|
||||||
from modules.logger import log_event
|
from modules.logger import log_event
|
||||||
|
|
||||||
# Tarification indicative par token OpenRouter (à synchroniser avec l'API en temps réel)
|
# Tarification indicative par token (À synchroniser avec OpenRouter)
|
||||||
TARIFS_OPENROUTER = {
|
TARIFS_OPENROUTER = {
|
||||||
"meta-llama/llama-3.1-8b-instruct:free": 0.0,
|
"meta-llama/llama-3.1-8b-instruct:free": 0.0,
|
||||||
"qwen/qwen-2.5-coder-32b-instruct:free": 0.0,
|
"qwen/qwen-2.5-coder-32b-instruct:free": 0.0,
|
||||||
"google/gemini-2.5-pro": 0.000005
|
"google/gemini-2.5-pro": 0.000005 # Exemple de modèle payant
|
||||||
}
|
}
|
||||||
|
|
||||||
def compter_tokens_local(prompt):
|
def compter_tokens(texte, modele="cl100k_base"):
|
||||||
"""Compte localement les tokens pour estimer le coût de la requête."""
|
"""Compte le nombre de tokens en local pour éviter les requêtes API inutiles."""
|
||||||
try:
|
try:
|
||||||
enc = tiktoken.get_encoding("cl100k_base")
|
enc = tiktoken.get_encoding(modele)
|
||||||
return len(enc.encode(prompt))
|
return len(enc.encode(texte))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log_event("ERROR", "BILLING", f"Erreur comptage tokens : {e}")
|
log_event("ERROR", "BILLING", f"Erreur lors du comptage des tokens : {e}")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def verifier_et_deduire_credit_utilisateur(prompt, modele_id, utilisateur_nom, solde_actuel_utilisateur):
|
def estimer_cout_facture(prompt, modele_id):
|
||||||
"""
|
"""
|
||||||
Vérifie si l'utilisateur a suffisamment de crédit.
|
Calcule le coût de la requête.
|
||||||
Applique la marge de 15% (Prix_HT = Coût_API / 0.85) pour les non-VIP.
|
Applique la marge stricte de 15% pour générer le Prix Facture HT.
|
||||||
Bloque la requête si le solde est insuffisant.
|
|
||||||
"""
|
"""
|
||||||
utilisateurs_vip = ["xavier", "céline", "anaëlle", "renan", "audric"]
|
tokens = compter_tokens(prompt)
|
||||||
|
|
||||||
tokens = compter_tokens_local(prompt)
|
|
||||||
cout_brut_api = tokens * TARIFS_OPENROUTER.get(modele_id, 0.0)
|
cout_brut_api = tokens * TARIFS_OPENROUTER.get(modele_id, 0.0)
|
||||||
|
|
||||||
if cout_brut_api <= 0.0:
|
if cout_brut_api == 0.0:
|
||||||
return True, 0.0 # Gratuit
|
return 0.0
|
||||||
|
|
||||||
if utilisateur_nom.lower() in utilisateurs_vip:
|
# Application stricte de votre formule comptable
|
||||||
log_event("INFO", "BILLING", f"Utilisateur VIP ({utilisateur_nom}) : Aucun prélèvement de marge ni de crédit.")
|
prix_facture_ht = cout_brut_api / 0.85
|
||||||
|
|
||||||
|
return round(prix_facture_ht, 6)
|
||||||
|
|
||||||
|
def verifier_et_valider_budget(prompt, modele_id, utilisateur_vip=False):
|
||||||
|
"""
|
||||||
|
Fonction appelée avant chaque requête par le Chat Handler.
|
||||||
|
Si le coût > 0 et que l'utilisateur n'a pas explicitement validé, on stoppe tout.
|
||||||
|
"""
|
||||||
|
cout_estime = estimer_cout_facture(prompt, modele_id)
|
||||||
|
|
||||||
|
# Les VIP ne paient pas de marge, on affiche juste le coût brut pour information
|
||||||
|
if utilisateur_vip:
|
||||||
|
log_event("INFO", "BILLING", f"Utilisateur VIP. Coût brut estimé de la requête : {cout_estime * 0.85} $")
|
||||||
return True, 0.0
|
return True, 0.0
|
||||||
|
|
||||||
# Application de la règle comptable de marge (15% de marge brute)
|
if cout_estime > 0.0:
|
||||||
prix_facture_ht = round(cout_brut_api / 0.85, 6)
|
# Lève une exception spécifique que l'interface FastHTML devra attraper pour afficher le pop-up
|
||||||
|
raise Exception(f"VALIDATION_PAIEMENT_REQUISE|{cout_estime}")
|
||||||
|
|
||||||
# Sécurité absolue : Empêche l'utilisateur de dépenser plus que son crédit versé
|
return True, cout_estime
|
||||||
if solde_actuel_utilisateur < prix_facture_ht:
|
|
||||||
log_event("WARNING", "BILLING", f"Rejet requête pour {utilisateur_nom} : Solde insuffisant ({solde_actuel_utilisateur}$ < {prix_facture_ht}$).")
|
|
||||||
raise Exception(f"SOLDE_INSUFFISANT|{prix_facture_ht}|{solde_actuel_utilisateur}")
|
|
||||||
|
|
||||||
return True, prix_facture_ht
|
|
||||||
@@ -69,7 +69,10 @@ def render_main_page(chat_id):
|
|||||||
Div(
|
Div(
|
||||||
A("+ Nouvelle discussion", href="/new_chat", cls="new-chat-btn"),
|
A("+ Nouvelle discussion", href="/new_chat", cls="new-chat-btn"),
|
||||||
A("💾 Exporter JSON", href="/export_json", target="_blank", cls="export-btn"),
|
A("💾 Exporter JSON", href="/export_json", target="_blank", cls="export-btn"),
|
||||||
|
# Module de don modifiable par l'hébergeur
|
||||||
render_paypal_donation_widget(),
|
render_paypal_donation_widget(),
|
||||||
|
# Module inaltérable (Licence EULA Aethas38)
|
||||||
|
A("❤️ Soutenir le créateur de ce projet", href="https://www.paypal.com/donate/?hosted_button_id=2B6T9UESCN2W6", target="_blank", style="margin-left: 10px; padding: 10px; background-color: #e2e8f0; color: #1a202c; border-radius: 5px; text-decoration: none; font-weight: bold; border: 1px solid #cbd5e0;"),
|
||||||
cls="nav-buttons"
|
cls="nav-buttons"
|
||||||
),
|
),
|
||||||
cls="sidebar-top"
|
cls="sidebar-top"
|
||||||
|
|||||||
Reference in new issue
Block a user