seo-dev-env 0.1.0__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.
- seo_dev_env-0.1.0/LICENSE.ls +0 -0
- seo_dev_env-0.1.0/PKG-INFO +538 -0
- seo_dev_env-0.1.0/README.md +512 -0
- seo_dev_env-0.1.0/seo/__init__.py +3 -0
- seo_dev_env-0.1.0/seo/generators.py +161 -0
- seo_dev_env-0.1.0/seo/templates/debutant/app.py +0 -0
- seo_dev_env-0.1.0/seo/templates/debutant/index.html +0 -0
- seo_dev_env-0.1.0/seo/templates/debutant/style.css +0 -0
- seo_dev_env-0.1.0/seo/templates/intermediaire/app/__init__.py +0 -0
- seo_dev_env-0.1.0/seo/templates/intermediaire/app/models.py +0 -0
- seo_dev_env-0.1.0/seo/templates/intermediaire/app/routes.py +0 -0
- seo_dev_env-0.1.0/seo/templates/intermediaire/config.py +0 -0
- seo_dev_env-0.1.0/seo/templates/intermediaire/run.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/__init__.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/api/__init__.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/api/v1/__init__.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/api/v1/endpoints.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/core/config.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/core/security.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/db/base.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/app/db/models.py +0 -0
- seo_dev_env-0.1.0/seo/templates/pro/docker-compose.yml +0 -0
- seo_dev_env-0.1.0/seo/utils.py +24 -0
- seo_dev_env-0.1.0/seo_dev_env.egg-info/PKG-INFO +538 -0
- seo_dev_env-0.1.0/seo_dev_env.egg-info/SOURCES.txt +29 -0
- seo_dev_env-0.1.0/seo_dev_env.egg-info/dependency_links.txt +1 -0
- seo_dev_env-0.1.0/seo_dev_env.egg-info/entry_points.txt +2 -0
- seo_dev_env-0.1.0/seo_dev_env.egg-info/requires.txt +2 -0
- seo_dev_env-0.1.0/seo_dev_env.egg-info/top_level.txt +1 -0
- seo_dev_env-0.1.0/setup.cfg +4 -0
- seo_dev_env-0.1.0/setup.py +35 -0
|
File without changes
|
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seo-dev-env
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Générateur d'environnements de développement pour tous niveaux
|
|
5
|
+
Home-page: https://github.com/https://github.com/elkast/seo-dev-env
|
|
6
|
+
Author: Votre Nom
|
|
7
|
+
Author-email: orsinimelchisedek@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE.ls
|
|
14
|
+
Requires-Dist: flask>=2.0.0
|
|
15
|
+
Requires-Dist: python-dotenv>=0.19.0
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: author-email
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: license-file
|
|
23
|
+
Dynamic: requires-dist
|
|
24
|
+
Dynamic: requires-python
|
|
25
|
+
Dynamic: summary
|
|
26
|
+
|
|
27
|
+
Très bien ! Voici une explication claire, complète et structurée de l'utilisation de **`seo-dev-env`**, un générateur d'environnements de développement Flask. L’objectif est que **même un débutant puisse comprendre** ce que chaque niveau fait, **comment les fichiers interagissent** et **ce qu’on peut construire avec**.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 🔧 Qu’est-ce que `seo-dev-env` ?
|
|
32
|
+
|
|
33
|
+
C’est un **outil Python** qui te permet de **créer un projet Flask prêt à l’emploi** avec une seule commande. Selon ton **niveau** (débutant, intermédiaire ou pro), il te génère automatiquement une structure de projet adaptée, propre et bien organisée.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 🚀 Installation
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install seo-dev-env
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Tu peux maintenant utiliser la commande `seo-create` ou l'importer dans un script Python.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ⚙️ Utilisation
|
|
48
|
+
|
|
49
|
+
### ➤ En ligne de commande (CLI)
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
seo-create debutant mon-projet
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Cela crée un projet nommé `mon-projet` avec une structure simple (pour débutant).
|
|
56
|
+
|
|
57
|
+
### ➤ En Python
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from seo import creer_projet
|
|
61
|
+
|
|
62
|
+
creer_projet('pro', 'mon-projet-élite')
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Cela génère un projet "pro" avec Docker et une API robuste.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 🧱 Niveaux disponibles et structure de projet
|
|
70
|
+
|
|
71
|
+
### 🐣 1. Débutant : Structure Simple
|
|
72
|
+
|
|
73
|
+
Idéal pour ceux qui apprennent Flask ou font un petit projet/test.
|
|
74
|
+
|
|
75
|
+
#### 🔹 Structure du dossier :
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
mon-projet/
|
|
79
|
+
├── app.py
|
|
80
|
+
├── templates/
|
|
81
|
+
│ └── index.html
|
|
82
|
+
├── static/
|
|
83
|
+
│ └── style.css
|
|
84
|
+
└── requirements.txt
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### 🔹 À quoi ça sert :
|
|
88
|
+
|
|
89
|
+
* `app.py` : ton fichier principal Flask
|
|
90
|
+
* `templates/index.html` : ta page HTML (Jinja2)
|
|
91
|
+
* `static/style.css` : ton style CSS
|
|
92
|
+
* `requirements.txt` : liste des bibliothèques Python à installer
|
|
93
|
+
|
|
94
|
+
#### ✅ Ce que tu peux construire :
|
|
95
|
+
|
|
96
|
+
* Une landing page
|
|
97
|
+
* Un formulaire de contact
|
|
98
|
+
* Une démo rapide pour un concept
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
### ⚡ 2. Intermédiaire : Architecture MVC
|
|
103
|
+
|
|
104
|
+
Architecture propre, réutilisable, bien structurée. Idéal pour un **site web dynamique** ou une **application complète**.
|
|
105
|
+
|
|
106
|
+
#### 🔹 Structure du dossier :
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
mon-projet/
|
|
110
|
+
├── app/
|
|
111
|
+
│ ├── __init__.py
|
|
112
|
+
│ ├── routes.py
|
|
113
|
+
│ ├── models.py
|
|
114
|
+
│ └── forms.py
|
|
115
|
+
├── templates/
|
|
116
|
+
│ └── base.html
|
|
117
|
+
│ └── home.html
|
|
118
|
+
├── static/
|
|
119
|
+
│ └── css/
|
|
120
|
+
├── config.py
|
|
121
|
+
├── run.py
|
|
122
|
+
└── requirements.txt
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
#### 🔹 Détail des fichiers :
|
|
126
|
+
|
|
127
|
+
* `app/__init__.py` : initialise l'app Flask
|
|
128
|
+
* `routes.py` : contient les pages et leurs comportements
|
|
129
|
+
* `models.py` : les objets liés à la base de données (SQLAlchemy)
|
|
130
|
+
* `forms.py` : formulaires (WTForms)
|
|
131
|
+
* `config.py` : configuration générale (dev, prod, clés secrètes)
|
|
132
|
+
* `run.py` : fichier pour lancer l’app
|
|
133
|
+
* `templates/` : toutes les pages HTML avec héritage de `base.html`
|
|
134
|
+
|
|
135
|
+
#### ✅ Ce que tu peux construire :
|
|
136
|
+
|
|
137
|
+
* Blog personnel
|
|
138
|
+
* Dashboard interne
|
|
139
|
+
* Site avec base de données (utilisateurs, commentaires, etc.)
|
|
140
|
+
* Application avec authentification/login
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### 🚀 3. Pro : Docker + API Pro
|
|
145
|
+
|
|
146
|
+
Projet conçu pour des applications **robustes, déployables en production**, avec Docker, API REST, structure scalable.
|
|
147
|
+
|
|
148
|
+
#### 🔹 Structure du dossier :
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
mon-projet-élite/
|
|
152
|
+
├── api/
|
|
153
|
+
│ ├── __init__.py
|
|
154
|
+
│ ├── routes/
|
|
155
|
+
│ │ └── user_routes.py
|
|
156
|
+
│ ├── models/
|
|
157
|
+
│ │ └── user_model.py
|
|
158
|
+
│ └── services/
|
|
159
|
+
│ └── auth_service.py
|
|
160
|
+
├── config/
|
|
161
|
+
│ └── config.py
|
|
162
|
+
├── docker/
|
|
163
|
+
│ └── Dockerfile
|
|
164
|
+
├── docker-compose.yml
|
|
165
|
+
├── requirements.txt
|
|
166
|
+
├── .env
|
|
167
|
+
└── run.py
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### 🔹 Détail des fichiers :
|
|
171
|
+
|
|
172
|
+
* `api/` : ton app Flask sous forme d’API modulaire
|
|
173
|
+
|
|
174
|
+
* `routes/` : routes REST (GET, POST, etc.)
|
|
175
|
+
* `models/` : objets de base de données (SQLAlchemy ou autre ORM)
|
|
176
|
+
* `services/` : logique métier (auth, traitement, etc.)
|
|
177
|
+
* `config/` : configuration centralisée
|
|
178
|
+
* `Dockerfile` & `docker-compose.yml` : pour l’environnement Docker
|
|
179
|
+
* `.env` : variables d’environnement sensibles
|
|
180
|
+
* `run.py` : point d’entrée de l’application
|
|
181
|
+
|
|
182
|
+
#### ✅ Ce que tu peux construire :
|
|
183
|
+
|
|
184
|
+
* Backend d’une app mobile
|
|
185
|
+
* API REST sécurisée
|
|
186
|
+
* Projet SaaS ou e-commerce scalable
|
|
187
|
+
* Application avec CI/CD, PostgreSQL, Redis, etc.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 🔁 Interaction des fichiers (exemples)
|
|
192
|
+
|
|
193
|
+
### Exemple pour le niveau **intermédiaire** :
|
|
194
|
+
|
|
195
|
+
1. `run.py` lance l'application
|
|
196
|
+
2. Il appelle `app/__init__.py` pour créer l’objet Flask
|
|
197
|
+
3. `init.py` charge les routes via `routes.py`
|
|
198
|
+
4. Les routes retournent des templates comme `home.html`
|
|
199
|
+
5. Les données viennent de `models.py`
|
|
200
|
+
6. Si besoin de formulaire, `forms.py` gère la validation
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 💡 Que peut-on faire de A à Z ?
|
|
205
|
+
|
|
206
|
+
Exemple : construire un **portail de gestion de projets**
|
|
207
|
+
|
|
208
|
+
1. Utilise `seo-create pro gestion-projets`
|
|
209
|
+
2. Ajoute une base PostgreSQL dans `docker-compose.yml`
|
|
210
|
+
3. Développe des routes pour :
|
|
211
|
+
|
|
212
|
+
* Créer un projet (`POST /projets`)
|
|
213
|
+
* Lister les projets (`GET /projets`)
|
|
214
|
+
* Ajouter des tâches à un projet (`POST /projets/<id>/taches`)
|
|
215
|
+
4. Gère l’authentification via JWT dans `services/auth_service.py`
|
|
216
|
+
5. Déploie avec Docker sur un VPS
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 🧠 Résumé des avantages
|
|
221
|
+
|
|
222
|
+
| Niveau | Idéal pour | Points forts |
|
|
223
|
+
| ------------- | ---------------------------- | ----------------------------------------- |
|
|
224
|
+
| Débutant | Apprentissage, mini-projets | Ultra simple, immédiat |
|
|
225
|
+
| Intermédiaire | Sites complets avec logique | MVC propre, bonne base pour la croissance |
|
|
226
|
+
| Pro | APIs, apps déployables, SaaS | Docker, structure modulaire, scalable |
|
|
227
|
+
|
|
228
|
+
un petit exmple😁👌;
|
|
229
|
+
|
|
230
|
+
Parfait ! Je vais te montrer un exemple complet avec le **niveau Intermédiaire (⚡ Architecture MVC)**, qui est un bon équilibre entre simplicité et puissance. Nous allons créer un **mini tableau de bord de gestion de tâches** (type Todo App multi-utilisateur).
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## 🎯 Objectif du projet : Gestion de tâches (Task Manager)
|
|
235
|
+
|
|
236
|
+
Chaque utilisateur peut :
|
|
237
|
+
|
|
238
|
+
* s’inscrire et se connecter,
|
|
239
|
+
* créer, modifier et supprimer ses tâches,
|
|
240
|
+
* voir ses tâches dans un tableau de bord.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 🧰 Étape 1 : Génération du projet
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
seo-create intermediaire task-manager
|
|
248
|
+
cd task-manager
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 🗂️ Structure du projet (générée automatiquement)
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
task-manager/
|
|
257
|
+
├── app/
|
|
258
|
+
│ ├── __init__.py
|
|
259
|
+
│ ├── routes.py
|
|
260
|
+
│ ├── models.py
|
|
261
|
+
│ └── forms.py
|
|
262
|
+
├── templates/
|
|
263
|
+
│ ├── base.html
|
|
264
|
+
│ ├── home.html
|
|
265
|
+
│ ├── login.html
|
|
266
|
+
│ └── dashboard.html
|
|
267
|
+
├── static/
|
|
268
|
+
│ └── style.css
|
|
269
|
+
├── config.py
|
|
270
|
+
├── run.py
|
|
271
|
+
└── requirements.txt
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 🔧 Étape 2 : Configurer la base
|
|
277
|
+
|
|
278
|
+
**config.py**
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
import os
|
|
282
|
+
|
|
283
|
+
class Config:
|
|
284
|
+
SECRET_KEY = 'cle-super-secrete'
|
|
285
|
+
SQLALCHEMY_DATABASE_URI = 'sqlite:///db.sqlite3'
|
|
286
|
+
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 🧱 Étape 3 : Initialiser l’app
|
|
292
|
+
|
|
293
|
+
**app/**init**.py**
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
from flask import Flask
|
|
297
|
+
from flask_sqlalchemy import SQLAlchemy
|
|
298
|
+
from flask_login import LoginManager
|
|
299
|
+
from config import Config
|
|
300
|
+
|
|
301
|
+
db = SQLAlchemy()
|
|
302
|
+
login = LoginManager()
|
|
303
|
+
login.login_view = 'login'
|
|
304
|
+
|
|
305
|
+
def create_app():
|
|
306
|
+
app = Flask(__name__)
|
|
307
|
+
app.config.from_object(Config)
|
|
308
|
+
|
|
309
|
+
db.init_app(app)
|
|
310
|
+
login.init_app(app)
|
|
311
|
+
|
|
312
|
+
from app.routes import bp
|
|
313
|
+
app.register_blueprint(bp)
|
|
314
|
+
|
|
315
|
+
return app
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## 👤 Étape 4 : Modèle utilisateur + tâche
|
|
321
|
+
|
|
322
|
+
**app/models.py**
|
|
323
|
+
|
|
324
|
+
```python
|
|
325
|
+
from app import db
|
|
326
|
+
from flask_login import UserMixin
|
|
327
|
+
from werkzeug.security import generate_password_hash, check_password_hash
|
|
328
|
+
from app import login
|
|
329
|
+
|
|
330
|
+
class User(UserMixin, db.Model):
|
|
331
|
+
id = db.Column(db.Integer, primary_key=True)
|
|
332
|
+
username = db.Column(db.String(64), unique=True)
|
|
333
|
+
password_hash = db.Column(db.String(128))
|
|
334
|
+
tasks = db.relationship('Task', backref='owner', lazy='dynamic')
|
|
335
|
+
|
|
336
|
+
def set_password(self, password):
|
|
337
|
+
self.password_hash = generate_password_hash(password)
|
|
338
|
+
|
|
339
|
+
def check_password(self, password):
|
|
340
|
+
return check_password_hash(self.password_hash, password)
|
|
341
|
+
|
|
342
|
+
@login.user_loader
|
|
343
|
+
def load_user(id):
|
|
344
|
+
return User.query.get(int(id))
|
|
345
|
+
|
|
346
|
+
class Task(db.Model):
|
|
347
|
+
id = db.Column(db.Integer, primary_key=True)
|
|
348
|
+
title = db.Column(db.String(128))
|
|
349
|
+
done = db.Column(db.Boolean, default=False)
|
|
350
|
+
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## 🧾 Étape 5 : Les formulaires
|
|
356
|
+
|
|
357
|
+
**app/forms.py**
|
|
358
|
+
|
|
359
|
+
```python
|
|
360
|
+
from flask_wtf import FlaskForm
|
|
361
|
+
from wtforms import StringField, PasswordField, SubmitField, BooleanField
|
|
362
|
+
from wtforms.validators import DataRequired, EqualTo
|
|
363
|
+
|
|
364
|
+
class LoginForm(FlaskForm):
|
|
365
|
+
username = StringField('Nom d\'utilisateur', validators=[DataRequired()])
|
|
366
|
+
password = PasswordField('Mot de passe', validators=[DataRequired()])
|
|
367
|
+
submit = SubmitField('Connexion')
|
|
368
|
+
|
|
369
|
+
class TaskForm(FlaskForm):
|
|
370
|
+
title = StringField('Titre de la tâche', validators=[DataRequired()])
|
|
371
|
+
submit = SubmitField('Ajouter')
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## 🌐 Étape 6 : Les routes principales
|
|
377
|
+
|
|
378
|
+
**app/routes.py**
|
|
379
|
+
|
|
380
|
+
```python
|
|
381
|
+
from flask import Blueprint, render_template, redirect, url_for, request, flash
|
|
382
|
+
from flask_login import login_user, logout_user, login_required, current_user
|
|
383
|
+
from app.models import User, Task
|
|
384
|
+
from app.forms import LoginForm, TaskForm
|
|
385
|
+
from app import db
|
|
386
|
+
|
|
387
|
+
bp = Blueprint('main', __name__)
|
|
388
|
+
|
|
389
|
+
@bp.route('/', methods=['GET', 'POST'])
|
|
390
|
+
def login():
|
|
391
|
+
form = LoginForm()
|
|
392
|
+
if form.validate_on_submit():
|
|
393
|
+
user = User.query.filter_by(username=form.username.data).first()
|
|
394
|
+
if user and user.check_password(form.password.data):
|
|
395
|
+
login_user(user)
|
|
396
|
+
return redirect(url_for('main.dashboard'))
|
|
397
|
+
flash('Identifiants invalides.')
|
|
398
|
+
return render_template('login.html', form=form)
|
|
399
|
+
|
|
400
|
+
@bp.route('/dashboard', methods=['GET', 'POST'])
|
|
401
|
+
@login_required
|
|
402
|
+
def dashboard():
|
|
403
|
+
form = TaskForm()
|
|
404
|
+
if form.validate_on_submit():
|
|
405
|
+
task = Task(title=form.title.data, owner=current_user)
|
|
406
|
+
db.session.add(task)
|
|
407
|
+
db.session.commit()
|
|
408
|
+
return redirect(url_for('main.dashboard'))
|
|
409
|
+
tasks = current_user.tasks.all()
|
|
410
|
+
return render_template('dashboard.html', tasks=tasks, form=form)
|
|
411
|
+
|
|
412
|
+
@bp.route('/logout')
|
|
413
|
+
def logout():
|
|
414
|
+
logout_user()
|
|
415
|
+
return redirect(url_for('main.login'))
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 🧪 Étape 7 : Initialisation de la base
|
|
421
|
+
|
|
422
|
+
Dans un terminal Python (depuis le dossier du projet) :
|
|
423
|
+
|
|
424
|
+
```python
|
|
425
|
+
from app import create_app, db
|
|
426
|
+
from app.models import User
|
|
427
|
+
|
|
428
|
+
app = create_app()
|
|
429
|
+
app.app_context().push()
|
|
430
|
+
db.create_all()
|
|
431
|
+
|
|
432
|
+
# Création d'un utilisateur test
|
|
433
|
+
u = User(username='admin')
|
|
434
|
+
u.set_password('admin')
|
|
435
|
+
db.session.add(u)
|
|
436
|
+
db.session.commit()
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
## 🖥️ Étape 8 : Templates HTML simplifiés
|
|
442
|
+
|
|
443
|
+
**templates/base.html**
|
|
444
|
+
|
|
445
|
+
```html
|
|
446
|
+
<!DOCTYPE html>
|
|
447
|
+
<html>
|
|
448
|
+
<head>
|
|
449
|
+
<title>{% block title %}Task Manager{% endblock %}</title>
|
|
450
|
+
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
|
451
|
+
</head>
|
|
452
|
+
<body>
|
|
453
|
+
{% block content %}{% endblock %}
|
|
454
|
+
</body>
|
|
455
|
+
</html>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**templates/login.html**
|
|
459
|
+
|
|
460
|
+
```html
|
|
461
|
+
{% extends "base.html" %}
|
|
462
|
+
{% block content %}
|
|
463
|
+
<h2>Connexion</h2>
|
|
464
|
+
<form method="post">
|
|
465
|
+
{{ form.hidden_tag() }}
|
|
466
|
+
{{ form.username.label }} {{ form.username() }}<br>
|
|
467
|
+
{{ form.password.label }} {{ form.password() }}<br>
|
|
468
|
+
{{ form.submit() }}
|
|
469
|
+
</form>
|
|
470
|
+
{% endblock %}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**templates/dashboard.html**
|
|
474
|
+
|
|
475
|
+
```html
|
|
476
|
+
{% extends "base.html" %}
|
|
477
|
+
{% block content %}
|
|
478
|
+
<h2>Bienvenue {{ current_user.username }}</h2>
|
|
479
|
+
<a href="{{ url_for('main.logout') }}">Déconnexion</a>
|
|
480
|
+
<form method="post">
|
|
481
|
+
{{ form.hidden_tag() }}
|
|
482
|
+
{{ form.title.label }} {{ form.title() }}
|
|
483
|
+
{{ form.submit() }}
|
|
484
|
+
</form>
|
|
485
|
+
<ul>
|
|
486
|
+
{% for task in tasks %}
|
|
487
|
+
<li>{{ task.title }} {% if task.done %}(fait){% endif %}</li>
|
|
488
|
+
{% endfor %}
|
|
489
|
+
</ul>
|
|
490
|
+
{% endblock %}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## 🌍 Étape 9 : Lancer l’application
|
|
496
|
+
|
|
497
|
+
**run.py**
|
|
498
|
+
|
|
499
|
+
```python
|
|
500
|
+
from app import create_app
|
|
501
|
+
|
|
502
|
+
app = create_app()
|
|
503
|
+
|
|
504
|
+
if __name__ == '__main__':
|
|
505
|
+
app.run(debug=True)
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Puis lance :
|
|
509
|
+
|
|
510
|
+
```bash
|
|
511
|
+
python run.py
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
## ☁️ Étape 10 : Déploiement (plusieurs options)
|
|
517
|
+
|
|
518
|
+
### Option simple : [Render](https://render.com)
|
|
519
|
+
|
|
520
|
+
1. Crée un repo GitHub et pousse ton code
|
|
521
|
+
2. Va sur render.com et connecte ton GitHub
|
|
522
|
+
3. Clique sur "New Web Service"
|
|
523
|
+
4. Paramètres :
|
|
524
|
+
|
|
525
|
+
* **Build Command** : `pip install -r requirements.txt`
|
|
526
|
+
* **Start Command** : `python run.py`
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## ✅ Résultat final
|
|
531
|
+
|
|
532
|
+
Tu as :
|
|
533
|
+
|
|
534
|
+
* Un système d'authentification
|
|
535
|
+
* Un tableau de bord utilisateur
|
|
536
|
+
* Un modèle MVC clair et extensible
|
|
537
|
+
* Une app Flask prête pour production (avec ajout facile de tests, Bootstrap, API, etc.)
|
|
538
|
+
|