blueprint-modular 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: blueprint-modular
3
+ Version: 0.1.1
4
+ Summary: Briques Python prêtes à l'emploi pour vos interfaces de données
5
+ Author-email: Rémi <contact@blueprint-modular.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://blueprint-modular.com
8
+ Project-URL: Documentation, https://docs.blueprint-modular.com
9
+ Keywords: dashboard,ui,framework,python,data
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest>=7.0; extra == "dev"
21
+ Requires-Dist: black; extra == "dev"
22
+ Requires-Dist: ruff; extra == "dev"
23
+
24
+ # Blueprint Modular
25
+
26
+ **Briques prêtes à l'emploi. Vous écrivez la logique.**
27
+
28
+ Framework Python pour créer des interfaces de données sans HTML ni JS.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install blueprint-modular
34
+ ```
35
+
36
+ ## Utilisation rapide
37
+
38
+ ```bash
39
+ bpm --version
40
+ bpm init --name mon-app
41
+ cd mon-app
42
+ bpm run app.py
43
+ ```
44
+
45
+ En Python :
46
+
47
+ ```python
48
+ import bpm
49
+
50
+ bpm.title("Mon tableau de bord")
51
+ bpm.metric("CA", 142500, delta=3200)
52
+ bpm.table(df)
53
+ ```
54
+
55
+ ## Documentation
56
+
57
+ https://docs.blueprint-modular.com
58
+
59
+ ## Statut
60
+
61
+ Blueprint Modular est en développement actif (alpha).
62
+ Certaines fonctionnalités sont en cours d'implémentation.
63
+
64
+ ## Licence
65
+
66
+ MIT
67
+
68
+ ---
69
+
70
+ # Site de documentation (ce dépôt)
71
+
72
+ Site statique de documentation **Blueprint Modular** (BPM) : landing, composants et référence API. Projet isolé pour être hébergé sur un **domaine dédié** (OVH + VPS).
73
+
74
+ ---
75
+
76
+ ## Projet portable — une seule copie
77
+
78
+ **Pour reprendre le projet Blueprint Modular dans une autre instance Cursor :** copiez tout le dossier **`blueprint-modular`** (ce dossier). Un seul copier-coller suffit.
79
+
80
+ Ce dossier contient tout ce qui est lié au site Blueprint Modular :
81
+ - Les **3 pages du site** (accueil, Components, API Reference) pour déploiement sur un domaine à la racine
82
+ - Les **versions pour /api/docs** (sous-dossier `api-docs/`) pour intégration dans MyPortfolio
83
+ - Les **logos** (Logo BPM.png, Logo-BPM-nom.jpg, Logo-BPM-seul.png)
84
+ - Les **scripts de déploiement** (PowerShell et Bash) et le **guide** (DEPLOIEMENT_DOMAINE.md)
85
+ - Les **exemples Nginx** (HTTP et HTTPS)
86
+
87
+ Aucune dépendance au reste du repo : vous pouvez ouvrir uniquement ce dossier dans Cursor et tout éditer, prévisualiser et déployer.
88
+
89
+ ---
90
+
91
+ ## Structure du projet (frontend / backend)
92
+
93
+ | Dossier / fichier | Rôle |
94
+ |-------------------|------|
95
+ | **frontend/** | Tout le code client (UI, doc, composants). |
96
+ | **frontend/bpm/** | Composants React BPM + composants doc (DocNav, DocSidebar, DocLayout, CodeBlock). |
97
+ | **frontend/doc-app/** | Site doc en React (recommandé). Build : `cd frontend/doc-app && npm run build` → `dist/`. |
98
+ | **frontend/static/** | Site doc HTML statique : index.html, doc.css, get-started/, api-reference/, deploy/, knowledge-base/, cheat-sheet, components, reference. |
99
+ | **frontend/api-docs/** | Pages pour l'URL /api/docs (MyPortfolio). |
100
+ | **backend/** | Réservé au code serveur (API, etc.). Aucun backend pour l'instant — voir backend/README.md. |
101
+ | **deploy/** | Scripts de déploiement : setup.sh, update.sh, nginx.conf. |
102
+ | **Logo BPM.png**, **Logo-BPM-*** | Logos (racine). |
103
+ | **app.py** | Exemple d’app BPM : <code>bpm run app.py</code>. |
104
+ | **deploy_blueprint_modular.ps1** | Déploie **frontend/static/** + Logo vers le VPS. |
105
+ | **DEPLOIEMENT_DOMAINE.md** | Guide : DNS, Nginx, Certbot. |
106
+
107
+ *(Ancienne liste détaillée ci-dessous.)*
108
+
109
+ | Fichier / dossier | Rôle |
110
+ |------------------|------|
111
+ | **index.html** (dans frontend/static/) | **Page d'accueil doc** (headline BPM, installation rapide, liens Get started / API Reference / Deploy, What's new) |
112
+ | **doc.css** | Feuille de style commune du site doc (thème BPM, accent #d4af37, dark mode) |
113
+ | **get-started/** | Installation, Fundamentals, First app |
114
+ | **api-reference/** | Text, Data, Metrics, Charts, Inputs, Layout, Panels, Media, Status, Chat, Config |
115
+ | **bpm/** | Composants React BPM (Button, Panel, Table, etc.) + **composants doc** : DocNav, DocSidebar, DocLayout, CodeBlock. |
116
+ | **doc-app/** | **Site doc en React** : utilise uniquement les composants BPM. Build : `cd doc-app && npm run build` → `dist/`. |
117
+ | **app.py** | Exemple d’app BPM : <code>bpm run app.py</code> (voir Installation). |
118
+ | **deploy/** | **Scripts de déploiement** : setup.sh, update.sh, nginx.conf, CHECKLIST.md — voir deploy/README.md. |
119
+ | **.env.example** | Exemple pour .env sur le serveur (ENVIRONMENT=production). |
120
+ | **knowledge-base/** | FAQ, Troubleshooting |
121
+ | **cheat-sheet.html** | Cheat sheet (toutes les fonctions BPM) |
122
+ | **components.html** | Ancienne page catalogue composants (conservée si besoin) |
123
+ | **reference.html** | Ancienne référence API (conservée si besoin) |
124
+ | **Logo BPM.png** | Logo Blueprint Modular (accueil domaine) |
125
+ | **Logo-BPM-nom.jpg** | Logo avec nom (landing /api/docs) |
126
+ | **Logo-BPM-seul.png** | Logo seul (nav des pages /api/docs) |
127
+ | **api-docs/** | Versions des 3 pages pour l’URL /api/docs (voir api-docs/README.txt pour copier vers frontend/public) |
128
+ | **documentation/** | README indiquant que la doc est en HTML statique à la racine (voir ci-dessous). |
129
+ | **DEPLOIEMENT_DOMAINE.md** | Guide complet : DNS, Nginx, Certbot, déploiement |
130
+ | **nginx-bpm-domain.conf.example** | Exemple de vhost Nginx (HTTP seul, pour Certbot) |
131
+ | **nginx-bpm-domain-https.conf.example** | Exemple de vhost Nginx HTTPS complet (après Certbot) |
132
+ | **deploy_blueprint_modular.ps1** | Script PowerShell : copie des fichiers statiques (index, components, reference, logos) vers le VPS. |
133
+ | **deploy_blueprint_modular_full.ps1** | Script PowerShell : déploiement complet (app + static) via archive + SSH (puis `deploy/update.sh` sur le serveur). |
134
+ | **deploy_blueprint_modular.sh** | Script Bash (Linux / WSL) équivalent (fichiers statiques). |
135
+
136
+ Les liens internes du site à la racine utilisent `/`, `/components` et `/reference`. Les fichiers dans `api-docs/` utilisent `/api/docs`, `/api/docs/components`, `/api/docs/reference`.
137
+
138
+ ### Fichiers pour le déploiement
139
+
140
+ Le script **deploy_blueprint_modular.ps1** déploie **frontend/static/** et **Logo BPM.png** (à la racine). **favicon.ico** à la racine est optionnel.
141
+
142
+ ## Prévisualisation en local
143
+
144
+ **Site doc statique (HTML)** — depuis le dossier des fichiers statiques :
145
+
146
+ ```bash
147
+ cd frontend/static && python -m http.server 8080
148
+ # Puis ouvrir http://localhost:8080
149
+ ```
150
+
151
+ **Site doc (React + BPM)** — recommandé :
152
+
153
+ ```bash
154
+ cd frontend/doc-app && npm install && cp "../../Logo BPM.png" "public/Logo BPM.png" && npm run dev
155
+ # Puis ouvrir l’URL affichée (http://localhost:5173)
156
+ ```
157
+
158
+ ## Déploiement — www.blueprint-modular.com (fichiers statiques)
159
+
160
+ Le site doc est construit avec les **composants BPM** (React) dans **frontend/doc-app/**.
161
+
162
+ 1. En local : `cd frontend/doc-app && npm run build` → les fichiers sont dans **frontend/doc-app/dist/**.
163
+ 2. Déployer **frontend/doc-app/dist/** vers le VPS, ou utiliser **deploy_blueprint_modular.ps1** (depuis Windows) pour le site **HTML statique** (**frontend/static/**), ou **deploy/deploy-from-git.sh** (sur le serveur, après clone du repo — voir **deploy/README.md**).
164
+ 3. Nginx : servir les fichiers statiques (voir **deploy/nginx.conf** : `root` + `try_files`).
165
+
166
+ Repo : [github.com/remigit55/blueprint-modular](https://github.com/remigit55/blueprint-modular).
167
+
168
+ ---
169
+
170
+ ## Déploiement site statique (ancien / alternatif)
171
+
172
+ Pour déployer uniquement les **fichiers HTML statiques** :
173
+
174
+ 1. Lire **[DEPLOIEMENT_DOMAINE.md](./DEPLOIEMENT_DOMAINE.md)**.
175
+ 2. Configurer le DNS, créer le vhost Nginx (partir de **nginx-bpm-domain.conf.example**), Certbot, puis déployer les fichiers avec **deploy_blueprint_modular.ps1** ou **deploy_blueprint_modular.sh** (variables SERVER_IP, SSH_KEY à adapter).
176
+
177
+ ## Projet isolé (Cursor / VS Code)
178
+
179
+ Pour travailler uniquement sur Blueprint Modular sans charger tout le repo MyPortfolio : **Fichier → Ouvrir le dossier** → sélectionner le dossier **`blueprint-modular`** (et non la racine du repo). Tout le nécessaire pour éditer les HTML, prévisualiser et déployer est ici ; aucune dépendance Node ou Python n'est requise pour le site statique. Voir aussi la section **Projet portable** en tête de ce README.
@@ -0,0 +1,156 @@
1
+ # Blueprint Modular
2
+
3
+ **Briques prêtes à l'emploi. Vous écrivez la logique.**
4
+
5
+ Framework Python pour créer des interfaces de données sans HTML ni JS.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install blueprint-modular
11
+ ```
12
+
13
+ ## Utilisation rapide
14
+
15
+ ```bash
16
+ bpm --version
17
+ bpm init --name mon-app
18
+ cd mon-app
19
+ bpm run app.py
20
+ ```
21
+
22
+ En Python :
23
+
24
+ ```python
25
+ import bpm
26
+
27
+ bpm.title("Mon tableau de bord")
28
+ bpm.metric("CA", 142500, delta=3200)
29
+ bpm.table(df)
30
+ ```
31
+
32
+ ## Documentation
33
+
34
+ https://docs.blueprint-modular.com
35
+
36
+ ## Statut
37
+
38
+ Blueprint Modular est en développement actif (alpha).
39
+ Certaines fonctionnalités sont en cours d'implémentation.
40
+
41
+ ## Licence
42
+
43
+ MIT
44
+
45
+ ---
46
+
47
+ # Site de documentation (ce dépôt)
48
+
49
+ Site statique de documentation **Blueprint Modular** (BPM) : landing, composants et référence API. Projet isolé pour être hébergé sur un **domaine dédié** (OVH + VPS).
50
+
51
+ ---
52
+
53
+ ## Projet portable — une seule copie
54
+
55
+ **Pour reprendre le projet Blueprint Modular dans une autre instance Cursor :** copiez tout le dossier **`blueprint-modular`** (ce dossier). Un seul copier-coller suffit.
56
+
57
+ Ce dossier contient tout ce qui est lié au site Blueprint Modular :
58
+ - Les **3 pages du site** (accueil, Components, API Reference) pour déploiement sur un domaine à la racine
59
+ - Les **versions pour /api/docs** (sous-dossier `api-docs/`) pour intégration dans MyPortfolio
60
+ - Les **logos** (Logo BPM.png, Logo-BPM-nom.jpg, Logo-BPM-seul.png)
61
+ - Les **scripts de déploiement** (PowerShell et Bash) et le **guide** (DEPLOIEMENT_DOMAINE.md)
62
+ - Les **exemples Nginx** (HTTP et HTTPS)
63
+
64
+ Aucune dépendance au reste du repo : vous pouvez ouvrir uniquement ce dossier dans Cursor et tout éditer, prévisualiser et déployer.
65
+
66
+ ---
67
+
68
+ ## Structure du projet (frontend / backend)
69
+
70
+ | Dossier / fichier | Rôle |
71
+ |-------------------|------|
72
+ | **frontend/** | Tout le code client (UI, doc, composants). |
73
+ | **frontend/bpm/** | Composants React BPM + composants doc (DocNav, DocSidebar, DocLayout, CodeBlock). |
74
+ | **frontend/doc-app/** | Site doc en React (recommandé). Build : `cd frontend/doc-app && npm run build` → `dist/`. |
75
+ | **frontend/static/** | Site doc HTML statique : index.html, doc.css, get-started/, api-reference/, deploy/, knowledge-base/, cheat-sheet, components, reference. |
76
+ | **frontend/api-docs/** | Pages pour l'URL /api/docs (MyPortfolio). |
77
+ | **backend/** | Réservé au code serveur (API, etc.). Aucun backend pour l'instant — voir backend/README.md. |
78
+ | **deploy/** | Scripts de déploiement : setup.sh, update.sh, nginx.conf. |
79
+ | **Logo BPM.png**, **Logo-BPM-*** | Logos (racine). |
80
+ | **app.py** | Exemple d’app BPM : <code>bpm run app.py</code>. |
81
+ | **deploy_blueprint_modular.ps1** | Déploie **frontend/static/** + Logo vers le VPS. |
82
+ | **DEPLOIEMENT_DOMAINE.md** | Guide : DNS, Nginx, Certbot. |
83
+
84
+ *(Ancienne liste détaillée ci-dessous.)*
85
+
86
+ | Fichier / dossier | Rôle |
87
+ |------------------|------|
88
+ | **index.html** (dans frontend/static/) | **Page d'accueil doc** (headline BPM, installation rapide, liens Get started / API Reference / Deploy, What's new) |
89
+ | **doc.css** | Feuille de style commune du site doc (thème BPM, accent #d4af37, dark mode) |
90
+ | **get-started/** | Installation, Fundamentals, First app |
91
+ | **api-reference/** | Text, Data, Metrics, Charts, Inputs, Layout, Panels, Media, Status, Chat, Config |
92
+ | **bpm/** | Composants React BPM (Button, Panel, Table, etc.) + **composants doc** : DocNav, DocSidebar, DocLayout, CodeBlock. |
93
+ | **doc-app/** | **Site doc en React** : utilise uniquement les composants BPM. Build : `cd doc-app && npm run build` → `dist/`. |
94
+ | **app.py** | Exemple d’app BPM : <code>bpm run app.py</code> (voir Installation). |
95
+ | **deploy/** | **Scripts de déploiement** : setup.sh, update.sh, nginx.conf, CHECKLIST.md — voir deploy/README.md. |
96
+ | **.env.example** | Exemple pour .env sur le serveur (ENVIRONMENT=production). |
97
+ | **knowledge-base/** | FAQ, Troubleshooting |
98
+ | **cheat-sheet.html** | Cheat sheet (toutes les fonctions BPM) |
99
+ | **components.html** | Ancienne page catalogue composants (conservée si besoin) |
100
+ | **reference.html** | Ancienne référence API (conservée si besoin) |
101
+ | **Logo BPM.png** | Logo Blueprint Modular (accueil domaine) |
102
+ | **Logo-BPM-nom.jpg** | Logo avec nom (landing /api/docs) |
103
+ | **Logo-BPM-seul.png** | Logo seul (nav des pages /api/docs) |
104
+ | **api-docs/** | Versions des 3 pages pour l’URL /api/docs (voir api-docs/README.txt pour copier vers frontend/public) |
105
+ | **documentation/** | README indiquant que la doc est en HTML statique à la racine (voir ci-dessous). |
106
+ | **DEPLOIEMENT_DOMAINE.md** | Guide complet : DNS, Nginx, Certbot, déploiement |
107
+ | **nginx-bpm-domain.conf.example** | Exemple de vhost Nginx (HTTP seul, pour Certbot) |
108
+ | **nginx-bpm-domain-https.conf.example** | Exemple de vhost Nginx HTTPS complet (après Certbot) |
109
+ | **deploy_blueprint_modular.ps1** | Script PowerShell : copie des fichiers statiques (index, components, reference, logos) vers le VPS. |
110
+ | **deploy_blueprint_modular_full.ps1** | Script PowerShell : déploiement complet (app + static) via archive + SSH (puis `deploy/update.sh` sur le serveur). |
111
+ | **deploy_blueprint_modular.sh** | Script Bash (Linux / WSL) équivalent (fichiers statiques). |
112
+
113
+ Les liens internes du site à la racine utilisent `/`, `/components` et `/reference`. Les fichiers dans `api-docs/` utilisent `/api/docs`, `/api/docs/components`, `/api/docs/reference`.
114
+
115
+ ### Fichiers pour le déploiement
116
+
117
+ Le script **deploy_blueprint_modular.ps1** déploie **frontend/static/** et **Logo BPM.png** (à la racine). **favicon.ico** à la racine est optionnel.
118
+
119
+ ## Prévisualisation en local
120
+
121
+ **Site doc statique (HTML)** — depuis le dossier des fichiers statiques :
122
+
123
+ ```bash
124
+ cd frontend/static && python -m http.server 8080
125
+ # Puis ouvrir http://localhost:8080
126
+ ```
127
+
128
+ **Site doc (React + BPM)** — recommandé :
129
+
130
+ ```bash
131
+ cd frontend/doc-app && npm install && cp "../../Logo BPM.png" "public/Logo BPM.png" && npm run dev
132
+ # Puis ouvrir l’URL affichée (http://localhost:5173)
133
+ ```
134
+
135
+ ## Déploiement — www.blueprint-modular.com (fichiers statiques)
136
+
137
+ Le site doc est construit avec les **composants BPM** (React) dans **frontend/doc-app/**.
138
+
139
+ 1. En local : `cd frontend/doc-app && npm run build` → les fichiers sont dans **frontend/doc-app/dist/**.
140
+ 2. Déployer **frontend/doc-app/dist/** vers le VPS, ou utiliser **deploy_blueprint_modular.ps1** (depuis Windows) pour le site **HTML statique** (**frontend/static/**), ou **deploy/deploy-from-git.sh** (sur le serveur, après clone du repo — voir **deploy/README.md**).
141
+ 3. Nginx : servir les fichiers statiques (voir **deploy/nginx.conf** : `root` + `try_files`).
142
+
143
+ Repo : [github.com/remigit55/blueprint-modular](https://github.com/remigit55/blueprint-modular).
144
+
145
+ ---
146
+
147
+ ## Déploiement site statique (ancien / alternatif)
148
+
149
+ Pour déployer uniquement les **fichiers HTML statiques** :
150
+
151
+ 1. Lire **[DEPLOIEMENT_DOMAINE.md](./DEPLOIEMENT_DOMAINE.md)**.
152
+ 2. Configurer le DNS, créer le vhost Nginx (partir de **nginx-bpm-domain.conf.example**), Certbot, puis déployer les fichiers avec **deploy_blueprint_modular.ps1** ou **deploy_blueprint_modular.sh** (variables SERVER_IP, SSH_KEY à adapter).
153
+
154
+ ## Projet isolé (Cursor / VS Code)
155
+
156
+ Pour travailler uniquement sur Blueprint Modular sans charger tout le repo MyPortfolio : **Fichier → Ouvrir le dossier** → sélectionner le dossier **`blueprint-modular`** (et non la racine du repo). Tout le nécessaire pour éditer les HTML, prévisualiser et déployer est ici ; aucune dépendance Node ou Python n'est requise pour le site statique. Voir aussi la section **Projet portable** en tête de ce README.
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: blueprint-modular
3
+ Version: 0.1.1
4
+ Summary: Briques Python prêtes à l'emploi pour vos interfaces de données
5
+ Author-email: Rémi <contact@blueprint-modular.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://blueprint-modular.com
8
+ Project-URL: Documentation, https://docs.blueprint-modular.com
9
+ Keywords: dashboard,ui,framework,python,data
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.9
18
+ Description-Content-Type: text/markdown
19
+ Provides-Extra: dev
20
+ Requires-Dist: pytest>=7.0; extra == "dev"
21
+ Requires-Dist: black; extra == "dev"
22
+ Requires-Dist: ruff; extra == "dev"
23
+
24
+ # Blueprint Modular
25
+
26
+ **Briques prêtes à l'emploi. Vous écrivez la logique.**
27
+
28
+ Framework Python pour créer des interfaces de données sans HTML ni JS.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install blueprint-modular
34
+ ```
35
+
36
+ ## Utilisation rapide
37
+
38
+ ```bash
39
+ bpm --version
40
+ bpm init --name mon-app
41
+ cd mon-app
42
+ bpm run app.py
43
+ ```
44
+
45
+ En Python :
46
+
47
+ ```python
48
+ import bpm
49
+
50
+ bpm.title("Mon tableau de bord")
51
+ bpm.metric("CA", 142500, delta=3200)
52
+ bpm.table(df)
53
+ ```
54
+
55
+ ## Documentation
56
+
57
+ https://docs.blueprint-modular.com
58
+
59
+ ## Statut
60
+
61
+ Blueprint Modular est en développement actif (alpha).
62
+ Certaines fonctionnalités sont en cours d'implémentation.
63
+
64
+ ## Licence
65
+
66
+ MIT
67
+
68
+ ---
69
+
70
+ # Site de documentation (ce dépôt)
71
+
72
+ Site statique de documentation **Blueprint Modular** (BPM) : landing, composants et référence API. Projet isolé pour être hébergé sur un **domaine dédié** (OVH + VPS).
73
+
74
+ ---
75
+
76
+ ## Projet portable — une seule copie
77
+
78
+ **Pour reprendre le projet Blueprint Modular dans une autre instance Cursor :** copiez tout le dossier **`blueprint-modular`** (ce dossier). Un seul copier-coller suffit.
79
+
80
+ Ce dossier contient tout ce qui est lié au site Blueprint Modular :
81
+ - Les **3 pages du site** (accueil, Components, API Reference) pour déploiement sur un domaine à la racine
82
+ - Les **versions pour /api/docs** (sous-dossier `api-docs/`) pour intégration dans MyPortfolio
83
+ - Les **logos** (Logo BPM.png, Logo-BPM-nom.jpg, Logo-BPM-seul.png)
84
+ - Les **scripts de déploiement** (PowerShell et Bash) et le **guide** (DEPLOIEMENT_DOMAINE.md)
85
+ - Les **exemples Nginx** (HTTP et HTTPS)
86
+
87
+ Aucune dépendance au reste du repo : vous pouvez ouvrir uniquement ce dossier dans Cursor et tout éditer, prévisualiser et déployer.
88
+
89
+ ---
90
+
91
+ ## Structure du projet (frontend / backend)
92
+
93
+ | Dossier / fichier | Rôle |
94
+ |-------------------|------|
95
+ | **frontend/** | Tout le code client (UI, doc, composants). |
96
+ | **frontend/bpm/** | Composants React BPM + composants doc (DocNav, DocSidebar, DocLayout, CodeBlock). |
97
+ | **frontend/doc-app/** | Site doc en React (recommandé). Build : `cd frontend/doc-app && npm run build` → `dist/`. |
98
+ | **frontend/static/** | Site doc HTML statique : index.html, doc.css, get-started/, api-reference/, deploy/, knowledge-base/, cheat-sheet, components, reference. |
99
+ | **frontend/api-docs/** | Pages pour l'URL /api/docs (MyPortfolio). |
100
+ | **backend/** | Réservé au code serveur (API, etc.). Aucun backend pour l'instant — voir backend/README.md. |
101
+ | **deploy/** | Scripts de déploiement : setup.sh, update.sh, nginx.conf. |
102
+ | **Logo BPM.png**, **Logo-BPM-*** | Logos (racine). |
103
+ | **app.py** | Exemple d’app BPM : <code>bpm run app.py</code>. |
104
+ | **deploy_blueprint_modular.ps1** | Déploie **frontend/static/** + Logo vers le VPS. |
105
+ | **DEPLOIEMENT_DOMAINE.md** | Guide : DNS, Nginx, Certbot. |
106
+
107
+ *(Ancienne liste détaillée ci-dessous.)*
108
+
109
+ | Fichier / dossier | Rôle |
110
+ |------------------|------|
111
+ | **index.html** (dans frontend/static/) | **Page d'accueil doc** (headline BPM, installation rapide, liens Get started / API Reference / Deploy, What's new) |
112
+ | **doc.css** | Feuille de style commune du site doc (thème BPM, accent #d4af37, dark mode) |
113
+ | **get-started/** | Installation, Fundamentals, First app |
114
+ | **api-reference/** | Text, Data, Metrics, Charts, Inputs, Layout, Panels, Media, Status, Chat, Config |
115
+ | **bpm/** | Composants React BPM (Button, Panel, Table, etc.) + **composants doc** : DocNav, DocSidebar, DocLayout, CodeBlock. |
116
+ | **doc-app/** | **Site doc en React** : utilise uniquement les composants BPM. Build : `cd doc-app && npm run build` → `dist/`. |
117
+ | **app.py** | Exemple d’app BPM : <code>bpm run app.py</code> (voir Installation). |
118
+ | **deploy/** | **Scripts de déploiement** : setup.sh, update.sh, nginx.conf, CHECKLIST.md — voir deploy/README.md. |
119
+ | **.env.example** | Exemple pour .env sur le serveur (ENVIRONMENT=production). |
120
+ | **knowledge-base/** | FAQ, Troubleshooting |
121
+ | **cheat-sheet.html** | Cheat sheet (toutes les fonctions BPM) |
122
+ | **components.html** | Ancienne page catalogue composants (conservée si besoin) |
123
+ | **reference.html** | Ancienne référence API (conservée si besoin) |
124
+ | **Logo BPM.png** | Logo Blueprint Modular (accueil domaine) |
125
+ | **Logo-BPM-nom.jpg** | Logo avec nom (landing /api/docs) |
126
+ | **Logo-BPM-seul.png** | Logo seul (nav des pages /api/docs) |
127
+ | **api-docs/** | Versions des 3 pages pour l’URL /api/docs (voir api-docs/README.txt pour copier vers frontend/public) |
128
+ | **documentation/** | README indiquant que la doc est en HTML statique à la racine (voir ci-dessous). |
129
+ | **DEPLOIEMENT_DOMAINE.md** | Guide complet : DNS, Nginx, Certbot, déploiement |
130
+ | **nginx-bpm-domain.conf.example** | Exemple de vhost Nginx (HTTP seul, pour Certbot) |
131
+ | **nginx-bpm-domain-https.conf.example** | Exemple de vhost Nginx HTTPS complet (après Certbot) |
132
+ | **deploy_blueprint_modular.ps1** | Script PowerShell : copie des fichiers statiques (index, components, reference, logos) vers le VPS. |
133
+ | **deploy_blueprint_modular_full.ps1** | Script PowerShell : déploiement complet (app + static) via archive + SSH (puis `deploy/update.sh` sur le serveur). |
134
+ | **deploy_blueprint_modular.sh** | Script Bash (Linux / WSL) équivalent (fichiers statiques). |
135
+
136
+ Les liens internes du site à la racine utilisent `/`, `/components` et `/reference`. Les fichiers dans `api-docs/` utilisent `/api/docs`, `/api/docs/components`, `/api/docs/reference`.
137
+
138
+ ### Fichiers pour le déploiement
139
+
140
+ Le script **deploy_blueprint_modular.ps1** déploie **frontend/static/** et **Logo BPM.png** (à la racine). **favicon.ico** à la racine est optionnel.
141
+
142
+ ## Prévisualisation en local
143
+
144
+ **Site doc statique (HTML)** — depuis le dossier des fichiers statiques :
145
+
146
+ ```bash
147
+ cd frontend/static && python -m http.server 8080
148
+ # Puis ouvrir http://localhost:8080
149
+ ```
150
+
151
+ **Site doc (React + BPM)** — recommandé :
152
+
153
+ ```bash
154
+ cd frontend/doc-app && npm install && cp "../../Logo BPM.png" "public/Logo BPM.png" && npm run dev
155
+ # Puis ouvrir l’URL affichée (http://localhost:5173)
156
+ ```
157
+
158
+ ## Déploiement — www.blueprint-modular.com (fichiers statiques)
159
+
160
+ Le site doc est construit avec les **composants BPM** (React) dans **frontend/doc-app/**.
161
+
162
+ 1. En local : `cd frontend/doc-app && npm run build` → les fichiers sont dans **frontend/doc-app/dist/**.
163
+ 2. Déployer **frontend/doc-app/dist/** vers le VPS, ou utiliser **deploy_blueprint_modular.ps1** (depuis Windows) pour le site **HTML statique** (**frontend/static/**), ou **deploy/deploy-from-git.sh** (sur le serveur, après clone du repo — voir **deploy/README.md**).
164
+ 3. Nginx : servir les fichiers statiques (voir **deploy/nginx.conf** : `root` + `try_files`).
165
+
166
+ Repo : [github.com/remigit55/blueprint-modular](https://github.com/remigit55/blueprint-modular).
167
+
168
+ ---
169
+
170
+ ## Déploiement site statique (ancien / alternatif)
171
+
172
+ Pour déployer uniquement les **fichiers HTML statiques** :
173
+
174
+ 1. Lire **[DEPLOIEMENT_DOMAINE.md](./DEPLOIEMENT_DOMAINE.md)**.
175
+ 2. Configurer le DNS, créer le vhost Nginx (partir de **nginx-bpm-domain.conf.example**), Certbot, puis déployer les fichiers avec **deploy_blueprint_modular.ps1** ou **deploy_blueprint_modular.sh** (variables SERVER_IP, SSH_KEY à adapter).
176
+
177
+ ## Projet isolé (Cursor / VS Code)
178
+
179
+ Pour travailler uniquement sur Blueprint Modular sans charger tout le repo MyPortfolio : **Fichier → Ouvrir le dossier** → sélectionner le dossier **`blueprint-modular`** (et non la racine du repo). Tout le nécessaire pour éditer les HTML, prévisualiser et déployer est ici ; aucune dépendance Node ou Python n'est requise pour le site statique. Voir aussi la section **Projet portable** en tête de ce README.
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ blueprint_modular.egg-info/PKG-INFO
4
+ blueprint_modular.egg-info/SOURCES.txt
5
+ blueprint_modular.egg-info/dependency_links.txt
6
+ blueprint_modular.egg-info/entry_points.txt
7
+ blueprint_modular.egg-info/requires.txt
8
+ blueprint_modular.egg-info/top_level.txt
9
+ bpm/__init__.py
10
+ bpm/cli.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ bpm = bpm.cli:main
@@ -0,0 +1,5 @@
1
+
2
+ [dev]
3
+ pytest>=7.0
4
+ black
5
+ ruff
@@ -0,0 +1,234 @@
1
+ """
2
+ BPM — Blueprint Modular runtime.
3
+ Registry $ (refs réactives) et @ (inscription / décorateurs).
4
+ APIs composants (title, button, write, metric, etc.) pour bpm run app.py.
5
+ """
6
+ __version__ = "0.1.1"
7
+
8
+ from typing import Any, Callable, Optional, TypeVar
9
+
10
+ # --- Rendu : nœuds collectés pendant l'exécution du script ---
11
+ _current_nodes: list[dict[str, Any]] = []
12
+ _rerun_requested = False
13
+
14
+
15
+ class SessionState(dict):
16
+ """État persisté entre les runs (équivalent session_state)."""
17
+
18
+ def __getattr__(self, key: str) -> Any:
19
+ try:
20
+ return self[key]
21
+ except KeyError:
22
+ raise AttributeError(key)
23
+
24
+ def __setattr__(self, key: str, value: Any) -> None:
25
+ self[key] = value
26
+
27
+
28
+ # État de session partagé (une session par processus pour l'instant)
29
+ session_state = SessionState()
30
+
31
+
32
+ def _node(typ: str, **props: Any) -> None:
33
+ _current_nodes.append({"type": typ, "props": props})
34
+
35
+
36
+ def get_current_nodes() -> list[dict[str, Any]]:
37
+ """Retourne la liste des nœuds du run en cours (usage interne serveur)."""
38
+ return list(_current_nodes)
39
+
40
+
41
+ def reset_current_nodes() -> None:
42
+ """Réinitialise la liste des nœuds (usage interne serveur)."""
43
+ global _current_nodes, _rerun_requested
44
+ _current_nodes = []
45
+ _rerun_requested = False
46
+
47
+
48
+ def rerun() -> None:
49
+ """Demande un re-run du script (après interaction)."""
50
+ global _rerun_requested
51
+ _rerun_requested = True
52
+
53
+
54
+ def rerun_requested() -> bool:
55
+ """Indique si rerun() a été appelé (usage interne serveur)."""
56
+ return _rerun_requested
57
+
58
+
59
+ # --- APIs composants (enregistrent un nœud de rendu) ---
60
+ def title(text: str, level: int = 1) -> None:
61
+ _node("title", text=text, level=level)
62
+
63
+
64
+ def write(text: str) -> None:
65
+ _node("write", text=str(text))
66
+
67
+
68
+ def markdown(text: str) -> None:
69
+ _node("markdown", text=text)
70
+
71
+
72
+ def button(label: str, key: Optional[str] = None) -> bool:
73
+ """Retourne True si le bouton a été cliqué (côté serveur, après re-run)."""
74
+ _node("button", label=label, key=key or f"btn_{len(_current_nodes)}")
75
+ return session_state.get(f"_clicked_{key or f'btn_{len(_current_nodes)-1}'}") is True
76
+
77
+
78
+ def metric(label: str, value: Any, delta: Optional[Any] = None) -> None:
79
+ _node("metric", label=str(label), value=value, delta=delta)
80
+
81
+
82
+ def table(data: Any) -> None:
83
+ """Accepte une liste de dicts ou un objet avec .to_dict('records')."""
84
+ if hasattr(data, "to_dict"):
85
+ rows = data.to_dict("records")
86
+ elif isinstance(data, list) and data and isinstance(data[0], dict):
87
+ rows = data
88
+ else:
89
+ rows = list(data) if data else []
90
+ _node("table", rows=rows)
91
+
92
+
93
+ def header(text: str) -> None:
94
+ _node("header", text=text)
95
+
96
+
97
+ def subheader(text: str) -> None:
98
+ _node("subheader", text=text)
99
+
100
+
101
+ def caption(text: str) -> None:
102
+ _node("caption", text=text)
103
+
104
+
105
+ def code(code: str, language: str = "python") -> None:
106
+ _node("code", code=code, language=language)
107
+
108
+
109
+ def divider() -> None:
110
+ _node("divider")
111
+
112
+
113
+ def toggle(label: str, value: bool = False, key: Optional[str] = None) -> bool:
114
+ _node("toggle", label=label, value=value, key=key or f"toggle_{len(_current_nodes)}")
115
+ return session_state.get(f"_toggle_{key or f'toggle_{len(_current_nodes)-1}'}", value)
116
+
117
+
118
+ def panel(title_text: str, body: str = "", variant: str = "info") -> None:
119
+ _node("panel", title=title_text, body=body, variant=variant)
120
+
121
+
122
+ def set_page_config(
123
+ page_title: str = "BPM App",
124
+ layout: str = "centered",
125
+ **kwargs: Any,
126
+ ) -> None:
127
+ """Configure la page (titre, layout). Pour l'instant enregistré mais pas utilisé par le rendu."""
128
+ _node("page_config", page_title=page_title, layout=layout, **kwargs)
129
+
130
+
131
+ # --- Registry @ : stockage par nom ---
132
+ _REGISTRY: dict[str, Any] = {}
133
+
134
+
135
+ def register(name: str, value: Any) -> None:
136
+ """Enregistre une valeur sous un nom (@)."""
137
+ _REGISTRY[name] = value
138
+
139
+
140
+ def get_registered(name: str) -> Any:
141
+ """Retourne la valeur enregistrée sous ce nom."""
142
+ return _REGISTRY.get(name)
143
+
144
+
145
+ # --- Refs réactives $ ---
146
+ _REFS: dict[str, Any] = {}
147
+ _REF_SUBSCRIBERS: dict[str, list[Callable[[Any], None]]] = {}
148
+
149
+
150
+ class Ref:
151
+ """Réf réactive : get/set/subscribe."""
152
+
153
+ def __init__(self, name: str, initial: Any = None):
154
+ self._name = name
155
+ if name not in _REFS:
156
+ _REFS[name] = initial
157
+ if name not in _REF_SUBSCRIBERS:
158
+ _REF_SUBSCRIBERS[name] = []
159
+
160
+ def get(self) -> Any:
161
+ return _REFS.get(self._name)
162
+
163
+ def set(self, value: Any) -> None:
164
+ _REFS[self._name] = value
165
+ for cb in _REF_SUBSCRIBERS.get(self._name, []):
166
+ cb(value)
167
+
168
+ def subscribe(self, callback: Callable[[Any], None]) -> Callable[[], None]:
169
+ _REF_SUBSCRIBERS.setdefault(self._name, []).append(callback)
170
+
171
+ def unsubscribe():
172
+ _REF_SUBSCRIBERS[self._name].remove(callback)
173
+
174
+ return unsubscribe
175
+
176
+
177
+ def ref(name: str, initial: Any = None) -> Ref:
178
+ """Crée ou récupère une ref réactive ($)."""
179
+ return Ref(name, initial)
180
+
181
+
182
+ # --- Décorateurs @ ---
183
+ F = TypeVar("F", bound=Callable[..., Any])
184
+
185
+
186
+ def page(page_id: str) -> Callable[[F], F]:
187
+ """Décorateur : enregistre une fonction comme page (@bpm.page('id'))."""
188
+
189
+ def decorator(fn: F) -> F:
190
+ register(f"page:{page_id}", fn)
191
+ return fn
192
+
193
+ return decorator
194
+
195
+
196
+ def sidebar(fn: F) -> F:
197
+ """Décorateur : enregistre le contenu de la sidebar (@bpm.sidebar)."""
198
+ register("sidebar", fn)
199
+ return fn
200
+
201
+
202
+ def cache_data(fn: F) -> F:
203
+ """Décorateur : cache le résultat de la fonction (@bpm.cache_data). Stub : pas de cache pour l'instant."""
204
+ return fn
205
+
206
+
207
+ __all__ = [
208
+ "set_page_config",
209
+ "register",
210
+ "get_registered",
211
+ "ref",
212
+ "Ref",
213
+ "page",
214
+ "sidebar",
215
+ "cache_data",
216
+ "session_state",
217
+ "get_current_nodes",
218
+ "reset_current_nodes",
219
+ "rerun",
220
+ "rerun_requested",
221
+ "title",
222
+ "write",
223
+ "markdown",
224
+ "button",
225
+ "metric",
226
+ "table",
227
+ "header",
228
+ "subheader",
229
+ "caption",
230
+ "code",
231
+ "divider",
232
+ "toggle",
233
+ "panel",
234
+ ]
@@ -0,0 +1,245 @@
1
+ """
2
+ CLI BPM — bpm run app.py, bpm init.
3
+ Point d'entrée : bpm = bpm.cli:main
4
+ """
5
+ from __future__ import annotations
6
+
7
+ import argparse
8
+ import json
9
+ import os
10
+ import runpy
11
+ import sys
12
+ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
13
+ from typing import Optional
14
+ from urllib.parse import parse_qs, urlparse
15
+
16
+ # Import après que le répertoire de travail soit celui de l'app
17
+ def _run_script(script_path: str) -> list:
18
+ """Exécute script_path et retourne la liste des nœuds de rendu."""
19
+ import bpm
20
+ bpm.reset_current_nodes()
21
+ script_dir = os.path.abspath(os.path.dirname(script_path))
22
+ if script_dir not in sys.path:
23
+ sys.path.insert(0, script_dir)
24
+ old_cwd = os.getcwd()
25
+ try:
26
+ os.chdir(script_dir)
27
+ runpy.run_path(script_path, run_name="__main__")
28
+ return bpm.get_current_nodes()
29
+ finally:
30
+ os.chdir(old_cwd)
31
+ if script_dir in sys.path:
32
+ sys.path.remove(script_dir)
33
+
34
+
35
+ def _nodes_to_html(nodes: list) -> str:
36
+ """Génère une page HTML qui affiche les nœuds (rendu minimal côté client)."""
37
+ nodes_js = json.dumps(nodes, default=str, ensure_ascii=False)
38
+ return f"""<!DOCTYPE html>
39
+ <html lang="fr">
40
+ <head>
41
+ <meta charset="utf-8" />
42
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
43
+ <title>BPM App</title>
44
+ <style>
45
+ body {{ font-family: system-ui, sans-serif; margin: 1rem 2rem; max-width: 800px; }}
46
+ .bpm-title {{ font-size: 1.5rem; font-weight: 700; margin: 1rem 0; }}
47
+ .bpm-write {{ margin: 0.5rem 0; }}
48
+ .bpm-metric {{ display: inline-block; padding: 1rem; margin: 0.5rem; background: #f0f0f0; border-radius: 8px; }}
49
+ .bpm-metric .value {{ font-size: 1.5rem; font-weight: 700; }}
50
+ .bpm-metric .delta {{ font-size: 0.85rem; color: #666; }}
51
+ .bpm-button {{ padding: 0.5rem 1rem; margin: 0.25rem; cursor: pointer; background: #1A4B8F; color: #fff; border: none; border-radius: 6px; }}
52
+ .bpm-button:hover {{ opacity: 0.9; }}
53
+ table {{ border-collapse: collapse; width: 100%; margin: 1rem 0; }}
54
+ th, td {{ border: 1px solid #ddd; padding: 0.5rem; text-align: left; }}
55
+ th {{ background: #f5f5f5; }}
56
+ .bpm-panel {{ padding: 1rem; margin: 1rem 0; border-radius: 8px; border-left: 4px solid #00A3E0; background: #f8f9fa; }}
57
+ .bpm-code {{ background: #1e1e1e; color: #d4d4d4; padding: 1rem; border-radius: 6px; overflow-x: auto; font-family: monospace; font-size: 0.9rem; }}
58
+ hr {{ margin: 1rem 0; border: none; border-top: 1px solid #eee; }}
59
+ </style>
60
+ </head>
61
+ <body>
62
+ <div id="root"></div>
63
+ <script>
64
+ const nodes = {nodes_js};
65
+ const root = document.getElementById('root');
66
+ function render(nodes) {{
67
+ root.innerHTML = '';
68
+ nodes.forEach(n => {{
69
+ const div = document.createElement('div');
70
+ div.className = 'bpm-' + n.type;
71
+ if (n.type === 'title') {{
72
+ const el = document.createElement('h' + (n.props.level || 1));
73
+ el.textContent = n.props.text;
74
+ root.appendChild(el);
75
+ }} else if (n.type === 'write' || n.type === 'markdown') {{
76
+ const p = document.createElement('div');
77
+ p.innerHTML = n.props.text;
78
+ root.appendChild(p);
79
+ }} else if (n.type === 'button') {{
80
+ const btn = document.createElement('button');
81
+ btn.className = 'bpm-button';
82
+ btn.textContent = n.props.label;
83
+ btn.onclick = () => {{ window.location.href = '/?clicked=' + encodeURIComponent(n.props.key || n.props.label); }};
84
+ root.appendChild(btn);
85
+ }} else if (n.type === 'metric') {{
86
+ const m = document.createElement('div');
87
+ m.className = 'bpm-metric';
88
+ m.innerHTML = '<div class="value">' + n.props.value + '</div><div>' + n.props.label + '</div>' +
89
+ (n.props.delta != null ? '<div class="delta">' + n.props.delta + '</div>' : '');
90
+ root.appendChild(m);
91
+ }} else if (n.type === 'table') {{
92
+ const t = document.createElement('table');
93
+ const rows = n.props.rows || [];
94
+ if (rows.length) {{
95
+ const thead = document.createElement('thead');
96
+ const tr = document.createElement('tr');
97
+ Object.keys(rows[0]).forEach(k => {{ const th = document.createElement('th'); th.textContent = k; tr.appendChild(th); }});
98
+ thead.appendChild(tr); t.appendChild(thead);
99
+ const tbody = document.createElement('tbody');
100
+ rows.forEach(row => {{ const tr = document.createElement('tr'); Object.values(row).forEach(v => {{ const td = document.createElement('td'); td.textContent = v; tr.appendChild(td); }}); tbody.appendChild(tr); }});
101
+ t.appendChild(tbody);
102
+ }}
103
+ root.appendChild(t);
104
+ }} else if (n.type === 'header') {{
105
+ const h = document.createElement('h2');
106
+ h.textContent = n.props.text;
107
+ root.appendChild(h);
108
+ }} else if (n.type === 'subheader') {{
109
+ const h = document.createElement('h3');
110
+ h.textContent = n.props.text;
111
+ root.appendChild(h);
112
+ }} else if (n.type === 'caption') {{
113
+ const p = document.createElement('p');
114
+ p.style.color = '#666'; p.style.fontSize = '0.9rem';
115
+ p.textContent = n.props.text;
116
+ root.appendChild(p);
117
+ }} else if (n.type === 'code') {{
118
+ const pre = document.createElement('pre');
119
+ pre.className = 'bpm-code';
120
+ pre.textContent = n.props.code;
121
+ root.appendChild(pre);
122
+ }} else if (n.type === 'divider') {{
123
+ root.appendChild(document.createElement('hr'));
124
+ }} else if (n.type === 'panel') {{
125
+ const p = document.createElement('div');
126
+ p.className = 'bpm-panel';
127
+ p.innerHTML = '<strong>' + n.props.title + '</strong><br/>' + (n.props.body || '');
128
+ root.appendChild(p);
129
+ }} else {{
130
+ const p = document.createElement('p');
131
+ p.textContent = JSON.stringify(n);
132
+ root.appendChild(p);
133
+ }}
134
+ }});
135
+ }}
136
+ render(nodes);
137
+ </script>
138
+ </body>
139
+ </html>"""
140
+
141
+
142
+ def run(script_path: str, port: int = 8501, host: str = "127.0.0.1") -> None:
143
+ """Lance le serveur BPM qui exécute script_path à chaque requête."""
144
+ script_path = os.path.abspath(script_path)
145
+ if not os.path.isfile(script_path):
146
+ print(f"Erreur : fichier introuvable {script_path}", file=sys.stderr)
147
+ sys.exit(1)
148
+
149
+ class BPMHandler(BaseHTTPRequestHandler):
150
+ def do_GET(self):
151
+ parsed = urlparse(self.path)
152
+ query = parse_qs(parsed.query)
153
+ # Marquer un bouton cliqué pour le prochain run
154
+ clicked = query.get("clicked", [None])[0]
155
+ if clicked:
156
+ import bpm
157
+ bpm.session_state["_clicked_" + clicked] = True
158
+ try:
159
+ nodes = _run_script(script_path)
160
+ # Consommer le clic après le run pour que le bouton ne reste pas True
161
+ import bpm
162
+ for k in list(bpm.session_state.keys()):
163
+ if k.startswith("_clicked_"):
164
+ del bpm.session_state[k]
165
+ except Exception as e:
166
+ self.send_response(500)
167
+ self.send_header("Content-type", "text/html; charset=utf-8")
168
+ self.end_headers()
169
+ self.wfile.write(
170
+ f"<html><body><h1>Erreur</h1><pre>{e!r}</pre></body></html>".encode("utf-8")
171
+ )
172
+ return
173
+ html = _nodes_to_html(nodes)
174
+ self.send_response(200)
175
+ self.send_header("Content-type", "text/html; charset=utf-8")
176
+ self.end_headers()
177
+ self.wfile.write(html.encode("utf-8"))
178
+
179
+ def log_message(self, format, *args):
180
+ print(f"[BPM] {args[0]}")
181
+
182
+ server = ThreadingHTTPServer((host, port), BPMHandler)
183
+ print(f"BPM : app servie sur http://{host}:{port}")
184
+ print(f" Script : {script_path}")
185
+ print(" Arrêt : Ctrl+C")
186
+ try:
187
+ server.serve_forever()
188
+ except KeyboardInterrupt:
189
+ server.shutdown()
190
+
191
+
192
+ def init(name: str = "mon-app") -> None:
193
+ """Scaffold une app BPM vide (dossier avec app.py, README.md, requirements.txt)."""
194
+ os.makedirs(name, exist_ok=True)
195
+ app_py = os.path.join(name, "app.py")
196
+ if os.path.exists(app_py):
197
+ print(f"Le dossier '{name}' contient déjà app.py.", file=sys.stderr)
198
+ sys.exit(1)
199
+ with open(app_py, "w", encoding="utf-8") as f:
200
+ f.write('''import bpm
201
+
202
+ bpm.set_page_config(page_title="Mon App", layout="wide")
203
+ bpm.title("Mon App Blueprint Modular")
204
+ bpm.write("Bienvenue sur votre première app BPM.")
205
+
206
+ bpm.metric("Valeur exemple", 142500, delta=3200)
207
+ ''')
208
+ with open(os.path.join(name, "README.md"), "w", encoding="utf-8") as f:
209
+ f.write(f"# {name}\n\nApp Blueprint Modular.\n\n## Lancer\n\n```\nbpm run app.py\n```\n")
210
+ with open(os.path.join(name, "requirements.txt"), "w", encoding="utf-8") as f:
211
+ f.write("blueprint-modular>=0.1.0\n")
212
+ print(f"App '{name}' créée.")
213
+ print(f" cd {name}")
214
+ print(f" bpm run app.py")
215
+
216
+
217
+ def main() -> None:
218
+ from bpm import __version__
219
+ parser = argparse.ArgumentParser(
220
+ prog="bpm",
221
+ description="Blueprint Modular — Framework Python pour interfaces de données",
222
+ )
223
+ parser.add_argument(
224
+ "--version", "-v",
225
+ action="version",
226
+ version=f"blueprint-modular {__version__}",
227
+ )
228
+ sub = parser.add_subparsers(dest="command")
229
+ run_parser = sub.add_parser("run", help="Lancer une app BPM")
230
+ run_parser.add_argument("file", nargs="?", default="app.py", help="Fichier Python (défaut: app.py)")
231
+ run_parser.add_argument("--port", "-p", type=int, default=8501, help="Port (défaut: 8501)")
232
+ run_parser.add_argument("--host", default="127.0.0.1", help="Host (défaut: 127.0.0.1)")
233
+ init_parser = sub.add_parser("init", help="Scaffolder une app vide")
234
+ init_parser.add_argument("--name", default="mon-app", help="Nom du projet (défaut: mon-app)")
235
+ args = parser.parse_args()
236
+ if args.command == "run":
237
+ run(args.file, port=args.port, host=args.host)
238
+ elif args.command == "init":
239
+ init(args.name)
240
+ else:
241
+ parser.print_help()
242
+
243
+
244
+ if __name__ == "__main__":
245
+ main()
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "blueprint-modular"
7
+ version = "0.1.1"
8
+ description = "Briques Python prêtes à l'emploi pour vos interfaces de données"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ authors = [{ name = "Rémi", email = "contact@blueprint-modular.com" }]
13
+ keywords = ["dashboard", "ui", "framework", "python", "data"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.9",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ ]
23
+ dependencies = []
24
+
25
+ [project.optional-dependencies]
26
+ dev = ["pytest>=7.0", "black", "ruff"]
27
+
28
+ [project.scripts]
29
+ bpm = "bpm.cli:main"
30
+
31
+ [project.urls]
32
+ Homepage = "https://blueprint-modular.com"
33
+ Documentation = "https://docs.blueprint-modular.com"
34
+
35
+ [tool.setuptools.packages.find]
36
+ where = ["."]
37
+ include = ["bpm*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+