0% found this document useful (0 votes)
9 views14 pages

QUB SMART Reconstruction Plan

The QUB_SMART Project Reconstruction Plan outlines the steps to recreate a Flask web application, detailing its features such as user registration, database interactions, and templating. The document provides a comprehensive step-by-step guide from setting up the development environment to deploying the application using GitHub Actions. Key components include configuring the application, defining database models, building forms, implementing routes, and creating templates and static assets.

Uploaded by

021CIVQazi Adnan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views14 pages

QUB SMART Reconstruction Plan

The QUB_SMART Project Reconstruction Plan outlines the steps to recreate a Flask web application, detailing its features such as user registration, database interactions, and templating. The document provides a comprehensive step-by-step guide from setting up the development environment to deploying the application using GitHub Actions. Key components include configuring the application, defining database models, building forms, implementing routes, and creating templates and static assets.

Uploaded by

021CIVQazi Adnan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

# QUB_SMART Project Reconstruction Plan

This document will guide us through recreating the QUB_SMART Flask application step by step.
We'll mirror the original structure and functionality, from environment setup to deployment.

## Project Overview

QUB_SMART is a Flask-based web application featuring:


- User registration and login
- Database interactions via SQLAlchemy and SQLite
- WTForms for handling user inputs
- Templating with Jinja2 (HTML templates for home, login, register, profile)
- Static assets (CSS, images)
- Database migrations via Flask-Migrate
- CI/CD pipeline with GitHub Actions

## Step-by-Step Outline

1. **Set Up Development Environment**


2. **Create Project Scaffold**
3. **Configure Application (config.py)**
4. **Initialize Flask App (run.py and `app/__init__.py`)**
5. **Define Database Models (`app/models.py`)**
6. **Build Forms (`app/forms.py`)**
7. **Implement Routes (`app/routes.py`)**
8. **Create Templates (`app/templates/`)**
9. **Add Static Assets (`app/static/`)**
10. **Set Up Migrations Folder**
11. **Configure GitHub Actions for Deployment**
12. **Test and Run the Application**

---
## Step 1: Set Up Development Environment

1. **Install Python**: Ensure Python 3.8+ is installed.


2. **Create a virtual environment**:
```bash
python3 -m venv venv
source venv/bin/activate # macOS/Linux
# or
venv\Scriptsctivate # Windows
```
3. **Upgrade pip**:
```bash
pip install --upgrade pip
```
4. **Install project dependencies**:
```bash
pip install flask sqlalchemy flask-wtf flask-login flask-migrate python-dotenv
```
5. **Freeze requirements**:
```bash
pip freeze > requirements.txt
```

---

## Step 2: Create Project Scaffold

1. **Create root project folder**:


```bash
mkdir QUB_SMART && cd QUB_SMART
```
2. **Create subfolders and files**:
```bash
mkdir -p app/templates app/static/css app/static/images migrations
touch app/__init__.py app/models.py app/forms.py app/routes.py
touch config.py run.py requirements.txt .gitignore
```
3. **Initialize Git repository**:
```bash
git init
git branch -M main
```
4. **Add .gitignore**:
```gitignore
venv/
__pycache__/
*.pyc
*.sqlite3
.env
migrations/
```
5. **Commit initial scaffold**:
```bash
git add .
git commit -m "Initial project scaffold"
```

---

## Step 3: Configure Application (config.py)

1. **Create `config.py`**:
```python
import os
from dotenv import load_dotenv
basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, '.env'))

class Config:
SECRET_KEY = os.getenv('SECRET_KEY', 'you-will-never-guess')
SQLALCHEMY_DATABASE_URI = (
os.getenv('DATABASE_URL') or
'sqlite:///' + os.path.join(basedir, 'app.db')
)
SQLALCHEMY_TRACK_MODIFICATIONS = False
```
2. **Environment variables**:
- Create a `.env` file with:
```text
SECRET_KEY=your-secret-key
DATABASE_URL=
```
3. **Commit configuration**:
```bash
git add config.py .env
git commit -m "Add application configuration"
```

---

## Step 4: Initialize Flask App (`run.py` and `app/__init__.py`)

1. **`app/__init__.py`**:
```python
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from config import Config

db = SQLAlchemy()
migrate = Migrate()
login = LoginManager()
login.login_view = 'login'

def create_app(config_class=Config):
app = Flask(__name__)
app.config.from_object(config_class)

db.init_app(app)
migrate.init_app(app, db)
login.init_app(app)

from app import routes, models

return app
```
2. **`run.py`**:
```python
from app import create_app

app = create_app()

if __name__ == '__main__':
app.run(debug=True)
```
3. **Commit initialization**:
```bash
git add app/__init__.py run.py
git commit -m "Initialize Flask application"
```
---

## Step 5: Define Database Models (`app/models.py`)

1. **User model**:
```python
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
from app import db, login

class User(UserMixin, db.Model):


id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True, nullable=False)
email = db.Column(db.String(120), index=True, unique=True, nullable=False)
password_hash = db.Column(db.String(128))

def set_password(self, password):


self.password_hash = generate_password_hash(password)

def check_password(self, password):


return check_password_hash(self.password_hash, password)

@login.user_loader
def load_user(id):
return User.query.get(int(id))
```
2. **Commit models**:
```bash
git add app/models.py
git commit -m "Define database models"
```
---

## Step 6: Build Forms (`app/forms.py`)

1. **Registration and Login forms**:


```python
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Email, EqualTo, ValidationError
from app.models import User

class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
password2 = PasswordField(
'Repeat Password', validators=[DataRequired(), EqualTo('password')]
)
submit = SubmitField('Register')

def validate_username(self, username):


user = User.query.filter_by(username=username.data).first()
if user:
raise ValidationError('Please use a different username.')

def validate_email(self, email):


user = User.query.filter_by(email=email.data).first()
if user:
raise ValidationError('Please use a different email address.')

class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
remember_me = BooleanField('Remember Me')
submit = SubmitField('Sign In')
```
2. **Commit forms**:
```bash
git add app/forms.py
git commit -m "Add WTForms forms"
```

---

## Step 7: Implement Routes (`app/routes.py`)

1. **Basic routes**:
```python
from flask import render_template, flash, redirect, url_for, request
from flask_login import current_user, login_user, logout_user, login_required
from werkzeug.urls import url_parse
from app import app, db
from app.forms import RegistrationForm, LoginForm
from app.models import User

@app.route('/')
@app.route('/index')
def index():
return render_template('index.html', title='Home')

@app.route('/register', methods=['GET', 'POST'])


def register():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
flash('Congratulations, you are now a registered user!')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)

@app.route('/login', methods=['GET', 'POST'])


def login():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid email or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
next_page = url_parse(request.args.get('next') or '').path
if not next_page:
next_page = url_for('index')
return redirect(next_page)
return render_template('login.html', title='Sign In', form=form)

@app.route('/logout')
def logout():
logout_user()
return redirect(url_for('index'))

@app.route('/profile')
@login_required
def profile():
return render_template('profile.html', title='Profile')
```
2. **Commit routes**:
```bash
git add app/routes.py
git commit -m "Implement application routes"
```

---

## Step 8: Create Templates (`app/templates/`)

1. **`base.html`** with Bootstrap and nav:


```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ title }} - QUB_SMART</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
</head>
<body>
<nav>
<a href="{{ url_for('index') }}">Home</a>
{% if current_user.is_authenticated %}
<a href="{{ url_for('profile') }}">Profile</a>
<a href="{{ url_for('logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('register') }}">Register</a>
{% endif %}
</nav>
<div class="container">
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for msg in messages %}
<div class="flash">{{ msg }}</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
</body>
</html>
```
2. **`index.html`, `register.html`, `login.html`, `profile.html`** extending `base.html`.
3. **Commit templates**:
```bash
git add app/templates
git commit -m "Add HTML templates"
```

---

## Step 9: Add Static Assets (`app/static/`)

1. **`main.css`** in `static/css` for basic styling.


2. Place any logo or images in `static/images`.
3. **Commit assets**:
```bash
git add app/static
git commit -m "Add static assets"
```

---
## Step 10: Set Up Migrations Folder

1. **Initialize migrations**:
```bash
flask db init
```
2. **Create initial migration**:
```bash
flask db migrate -m "Initial migration"
```
3. **Apply migration**:
```bash
flask db upgrade
```
4. **Commit migrations**:
```bash
git add migrations
git commit -m "Set up database migrations"
```

---

## Step 11: Configure GitHub Actions for Deployment

1. **Create workflow file** at `.github/workflows/python-app.yml`:


```yaml
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, 3.10]
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest
```
2. **Commit workflow**:
```bash
git add .github/workflows/python-app.yml
git commit -m "Add GitHub Actions workflow"
```

---

## Step 12: Test and Run the Application

1. **Run locally**:
```bash
flask run
```
or
```bash
python run.py
```
2. **Test functionality**:
- Register a new user
- Log in and log out
- View profile page
3. **Automated tests (optional)**:
- Create tests under `tests/` and run with `pytest`.

---

Congratulations! You now have a complete, functioning QUB_SMART application.

You might also like