Setting Up the Project 🛠️

Angular Setup

ng new task-app
cd task-app
ng serve

Python & Flask Backend

python -m venv venv
source venv/bin/activate

With our environment consecrated, Flask stands ready to breathe life into our server-side logic.

Integrating SQL Database 🗃️

The heart of our application—a SQL database—is next. Here, Flask SQLAlchemy weaves together our data model:

from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tasks.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class Task(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)

@app.before_first_request
def create_tables():
    db.create_all()

@app.route('/task', methods=['POST'])
def add_task():
    data = request.get_json()
    new_task = Task(title=data['title'])
    db.session.add(new_task)
    db.session.commit()
    return jsonify({'message': 'Task created successfully'}), 201

@app.route('/tasks', methods=['GET'])
def get_tasks():
    tasks_query = Task.query.all()
    tasks = [{"id": task.id, "title": task.title} for task in tasks_query]
    return jsonify({'tasks': tasks})

@app.route('/task/<int:id>', methods=['PUT'])
def update_task(id):
    data = request.get_json()
    task = Task.query.filter_by(id=id).first()
    if not task:
        return jsonify({'message': 'Task not found'}), 404
    task.title = data['title']
    db.session.commit()
    return jsonify({'message': 'Task updated successfully'})

@app.route('/task/<int:id>', methods=['DELETE'])
def delete_task(id):
    task = Task.query.filter_by(id=id).first()
    if not task:
        return jsonify({'message': 'Task not found'}), 404
    db.session.delete(task)
    db.session.commit()
    return jsonify({'message': 'Task deleted successfully'})

if __name__ == '__main__':
    app.run(debug=True)

CSRF Protection with Angular

Angular, with its built-in CSRF defenses, ensures our application is fortified against cross-site request forgery:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class TaskService {
  constructor(private http: HttpClient) {}

  addTask(taskData: any) {
    return this.http.post('/api/tasks', taskData);
  }
}

This service acts as a conduit between our Angular frontend and Flask backend, ensuring tasks are managed with grace and efficiency.

CSRF Configuration in Flask

Ensuring Flask is prepared to parry CSRF attempts is paramount. Flask-WTF lends its strength to our defenses:

import os
from flask import Flask, render_template_string
from flask_wtf.csrf import CSRFProtect

app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', os.urandom(24))

csrf = CSRFProtect(app)

@app.route('/', methods=['GET', 'POST'])
def index():
    return render_template_string("...")

if __name__ == '__main__':
    app.run(debug=True)

With CSRFProtect invoked, our application is shielded, allowing us to focus on crafting user experiences without fear.