Final project for CWEB-1116
  • HTML 82.2%
  • Python 17.7%
Find a file
2026-05-21 13:11:44 -05:00
.api/final final changes 2026-05-21 12:13:43 -05:00
.vscode final changes 2026-05-21 12:13:43 -05:00
static feat: make admin select all button actually work 2026-05-20 16:23:05 -05:00
templates final changes 2026-05-21 12:13:43 -05:00
.gitignore chore: base project structure 2026-05-04 12:20:34 -05:00
app.py final changes 2026-05-21 12:13:43 -05:00
forms.py feat: switch new post form to WTforms to work with markdown 2026-05-20 15:46:09 -05:00
md.patch feat: update requirements and create git patch to fix bug in flask markdown 2026-05-20 15:41:23 -05:00
model.py final changes 2026-05-21 12:13:43 -05:00
README.md Add README.md 2026-05-21 13:11:44 -05:00
requirements.txt feat: update requirements and create git patch to fix bug in flask markdown 2026-05-20 15:41:23 -05:00

Flask blog

This will have to count has my blog post as my blag supports HTML. Going into this project my knowalge of python was limited but thanks to some cool third party libs I was able to save a long time.

Lib

flask-security

The first of which I used was flask-security which saved a huge amount of time by providing a simple framework for handling authentacation and RBAC although I did have to write some code to make decorrators to add support for the API key systme I created.

def api_key_and_role_required(role):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):

            if current_user.is_authenticated:
                if current_user.has_role(role):
                    return f(*args, **kwargs)
                else:
                    abort(403, 'No permission (missing role)')

            api_key = request.headers.get('X-API-KEY')
            if not api_key:
                return jsonify({'message':'API Key required'}), 401

            user = User.query.filter_by(api_key=api_key).first()
            if not user:
                return jsonify({'message':'Invalid API Key'}), 401

            if role is None: 
                return f(*args, **kwargs)
            
            if not any(r.name == role for r in user.roles):
                return jsonify({'message':'No permission (missing role)'}), 403
            return f(*args, **kwargs)
        return decorated_function
    return decorator
def api_key_or_auth_required():
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):

            if current_user.is_authenticated:
                return f(*args, **kwargs)

            api_key = request.headers.get('X-API-KEY')
            if not api_key:
                return jsonify({'message':'API Key required'}), 401

            user = User.query.filter_by(api_key=api_key).first()
            if not user:
                return jsonify({'message':'Invalid API Key'}), 401
            return f(*args, **kwargs)
        return decorated_function
    return decorator

Pagedown

Pagedown is the lib I use to support these very markdown posts that is displayed here. It took a while to actually get this working since it requires a wtform for my new post modal which took some time and for rendering I used flask-markdown which was annoying since I had to find a PR on the github repo as it was abandoned. Based on that PR I wrote the patch below

diff --git a/.venv/Lib/site-packages/flaskext/markdown.py b/.venv/Lib/site-packages/flaskext/markdown.py
index d334b4c..85062e6 100644
--- a/.venv/Lib/site-packages/flaskext/markdown.py	
+++ b/.venv/Lib/site-packages/flaskext/markdown.py
@@ -29,7 +29,15 @@ decorating the extension class with :func:`extend`
 :license: BSD, MIT see LICENSE for more details.
 """
 from __future__ import absolute_import
-from flask import Markup
+try:
+    from flask import Markup
+except:
+    from markupsafe import Markup
+try:
+    from jinja2 import evalcontextfilter, escape
+except:
+    from jinja2 import pass_eval_context as evalcontextfilter
+    from markupsafe import escape
 import markdown as md
 from markdown import (
     blockprocessors,

The journey

My coding journey has been a very long one so I will only cover this class. Going into the class I had done some very basic scripting in python and never touched flask as I had always used react. Throughout the class my skills developed and now I was able to create this entire site with the help of AI for only one database related method.