Bonjour Forge
La progression cœur : du premier affichage texte jusqu'à un CRUD complet à SQL visible, palier par palier (HTTP, vues, formulaires, base de données).
Framework web applicatif Python, explicite et auditable.
Forge entre en release candidate : l'API publique du cœur est gelée pour la 1.0. Le code que vous écrivez aujourd'hui contre la RC reste valide en 1.0.0 stable, sans rupture d'API.
Toutes les briques opt-in officielles passent en statut Beta. Chacune s'installe séparément et le cœur ne dépend d'aucune : votre application n'embarque que ce qu'elle utilise vraiment.
Cinq nouveaux opt-ins couvrent des besoins courants, adossés à MariaDB et sans magie : settings (paramètres), audit (journal applicatif), jobs (file de tâches de fond), notifications in-app et import/export CSV.
Le déploiement quitte le cœur pour l'opt-in CLI forge-mvc-deploy : forge deploy:init génère une configuration Nginx, systemd et Gunicorn à adapter, forge deploy:check valide l'environnement de production.
Installez Forge en quelques minutes sur Debian, Ubuntu ou Linux Mint.
pipx, sans modifier le Python système.
forge new.
Développez avec Forge sous Windows grâce à WSL et Ubuntu 24.04.
Les starters sont des projets pédagogiques pour apprendre Forge pas à pas.
La progression cœur : du premier affichage texte jusqu'à un CRUD complet à SQL visible, palier par palier (HTTP, vues, formulaires, base de données).
Recevoir, stocker et exposer des mesures de capteurs : configuration MQTT, lecture des événements, API HTTP JSON et subscriber temps réel.
La chaîne vidéo complète, brique par brique : upload, lecture en streaming, suivi d'état, sondage et transcodage MP4.
Téléverser, générer des variantes, attacher à une entité, gérer galerie et couverture, puis sécuriser l'upload contre les images piégées.
La brique d'upload générique : stockage sécurisé, service de fichiers, validation, limitation de débit et chemins anti-traversal.
Téléverser un audio, le lire en streaming, sonder ses métadonnées et le transcoder en MP3, sans état.
Le second facteur de bout en bout : secret TOTP, enrôlement, challenge de connexion, codes de récupération et durcissement.
Le contrôle d'accès par rôles : contrat déclaratif, vérification de permission, garde de route, helper de gabarit et résolution par utilisateur.
Statuts et transitions applicatives : déclarer les passages autorisés, les vérifier, puis afficher des badges de statut.
Le tracking d'événements à SQL visible : schéma, insertion, validation, consultation et normalisation des lignes.
Composer et envoyer des emails : transports interchangeables (console, SMTP, log), templates Jinja et diagnostic du module.
Internationaliser une application : catalogues JSON, locale par défaut et fallback, helper trans() dans les templates.
Les tables pivot enrichies : associations many_to_many avec attributs, et génération make:pivot-crud.
Générer des QR Codes PNG ou SVG depuis du texte ou une URL, et les servir depuis un contrôleur.
Persister des paramètres applicatifs en base : écrire et lire des valeurs typées via get_setting et set_setting.
Échanger des données en CSV : import validé champ par champ avec rapport d'erreurs, et export programmatique.
Tenir un journal d'audit applicatif : enregistrer et consulter des événements, borné et lisible.
Une file de tâches de fond adossée à MariaDB : enqueue et worker explicite, sans broker ni async.
Des notifications in-app : notifier un utilisateur, lister puis marquer comme lues.
Préparer la mise en production : générer la configuration Nginx, systemd et Gunicorn, puis vérifier l'environnement.
Un back-office applicatif : CRUD générique sur les entités déclarées, avec auth, CSRF et RBAC optionnel.
Construire vos propres façades applicatives (Session, Cookies, Flash) au-dessus du noyau minimal, sans alourdir Forge.
Rédiger une page de documentation Forge palier par palier : titres, listes, tableaux, encadrés, code, onglets, diagrammes et toutes les extensions Markdown.
Les briques Python publiques ou semi-publiques de Forge : configuration, HTTP, sessions, sécurité, WSGI.
Les commandes forge ... utilisées pour créer, diagnostiquer, générer et maintenir un projet Forge.
Les objets Request,
Response,
Router
et le fonctionnement des routes.
La structure mvc/routes.py et
mvc/controllers/
utilisée par les applications Forge.
L'entrée create_configured_wsgi_app() pour brancher Forge derrière un serveur WSGI externe (Gunicorn, …).
Accès à la documentation technique détaillée : modèle d'entités, schémas JSON, contrats publics.
Requêtes, réponses, routes nommées et contrôleurs explicites.
Structure claire : contrôleurs, modèles, vues, routes et formulaires.
Rendu serveur lisible, layouts publics/admin et composants simples.
Fichiers SQL auditables, sans ORM opaque imposé par défaut.
Une source canonique pour générer SQL, modèles et CRUD, avec des types explicites, dont le slug auto-généré depuis un champ source.
Migrations SQL versionnées, contrôlables et lisibles.
Back-office explicite, modifiable et non destructif, avec lecture par slug et unicité garantie.
Champs typés, validation serveur et messages clairs.
CSRF, sessions, headers HTTP, cookies durcis et audit complet.
Login, sessions, hachage Argon2id, vérification email et reset de mot de passe.
Tailwind officiel, HTMX recommandé, Alpine.js optionnel.
Validation du modèle d'entité, autocomplete VS Code et forge entity:validate.
Générer, vérifier, diagnostiquer et brancher les opt-in : famille unifiée opt-in:install / remove / enable / disable / list.
Nginx, systemd, check sécurité-prod du doctor, migrations en --dry-run et checklist de déploiement.
Endpoints JSON explicites avec auth Bearer, sans transformer Forge en moteur d'API.
Authentification multi-facteurs : TOTP, codes de récupération, challenge à la connexion.
Rôles, permissions fines, helpers Jinja et décorateurs @require_permission.
Statuts et transitions applicatives : brouillon → publié → archivé.
Tracking d'événements applicatifs génériques : page vues, clics, conversions.
Upload générique : écriture sécurisée anti-traversal, stockage et service de fichiers (HTTP Range).
Traitement d'images (Pillow) : variantes, galerie, couverture et garde anti-image-bombe à l'upload.
Réception et exposition de données IoT via MQTT : subscriber, stockage d'événements, API JSON.
Upload, transcodage MP4 (H.264/AAC) et lecture vidéo en streaming HTTP Range.
Upload, sondage (ffprobe), transcodage MP3 (ffmpeg) et lecture audio en streaming HTTP Range.
Envoi d'emails : composition, transports interchangeables (console, SMTP, log), templates Jinja et CLI mail:*.
Tables pivot enrichies : associations many_to_many avec attributs, générateur make:pivot-crud.
Internationalisation : traduction par catalogues JSON, locale par défaut et fallback, helper trans() pour les templates.
Génération de QR Codes PNG ou SVG depuis du texte ou une URL, réponse HTTP servable depuis un contrôleur.
Paramètres applicatifs persistés en MariaDB (table app_settings), API explicite get_setting et set_setting.
Échange CSV : import validé par champ avec rapport d'erreurs, et export programmatique to_csv.
Journal d'audit applicatif (table audit_log) : record_audit et get_audit_log, borné, pas un SIEM.
File de tâches de fond adossée à MariaDB : enqueue et worker explicite, sans broker ni async.
Notifications in-app (table notifications) : notify, get_notifications, mark_read.
Outillage de déploiement CLI-only : deploy:init (Nginx, systemd, wsgi.py) et deploy:check.
Back-office applicatif opt-in : CRUD générique sur les entités déclarées, auth, CSRF et RBAC optionnel.
Forge automatise les répétitions, mais les fichiers restent visibles, auditables et modifiables.
1. Tout part d'un fichier JSON d'entité canonique, source unique du modèle.
2. La commande forge entity:validate vérifie le contrat avant toute génération.
3. Le SQL et les migrations demeurent visibles et lisibles.
4. Le modèle *_base.py est régénéré à chaque exécution.
5. Le modèle manuel, lui, est toujours préservé.
6. Le contrôleur, le formulaire et les vues CRUD sont ensuite échafaudés.
7. Il en résulte une application MVC claire et maintenable.
$ forge new mon-app $ cd mon-app $ forge make:entity Contact $ forge make:crud Contact --dry-run $ forge make:crud Contact
{
"$schema": "../../schemas/entity.schema.json",
"schema_version": "1.0",
"name": "Contact",
"table": "contacts",
"label": "Contact",
"plural_label": "Contacts",
"fields": [
{ "name": "email", "type": "email", "required": true },
{ "name": "message", "type": "text", "required": true }
],
"options": { "timestamps": true }
}
$ forge make:crud Contact # Génère : [CRÉÉ] mvc/controllers/contact_controller.py [CRÉÉ] mvc/models/contact_model.py [CRÉÉ] mvc/forms/contact_form.py [CRÉÉ] mvc/views/contact/index.html [CRÉÉ] mvc/views/contact/show.html [CRÉÉ] mvc/views/contact/form.html
from core.http.router import Router from mvc.controllers.contact_controller import ContactController router = Router() with router.group("/contacts") as contacts: contacts.add("GET", "/", ContactController.index, name="contacts.index")
$ forge make:crud Contact --dry-run [DRY-RUN] mvc/controllers/contact_controller.py [DRY-RUN] mvc/models/contact_model.py [DRY-RUN] mvc/views/contact/form.html [DRY-RUN] Aucun fichier modifié. # Prévisualiser avant d'écrire. # Comprendre avant de modifier. # Garder la main.
Pour toute question sur Forge, retour d'usage, remontée de bug ou demande de licence.
Roger Lequette · forgemvc@gmail.com
Écrire à Forge