Skip to content

Commit 147f164

Browse files
committed
Upgrade to Python 3.10; resolve dependency changes; minor refactor.
1 parent b02521d commit 147f164

File tree

13 files changed

+196
-170
lines changed

13 files changed

+196
-170
lines changed

.env.example

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
11
ENVIRONMENT=production
2-
FLASK_DEBUG=false
3-
SECRET_KEY=randomstringofcharacters
4-
5-
LESS_BIN=/usr/local/bin/lessc
6-
ASSETS_DEBUG=False
7-
LESS_RUN_IN_DEBUG=False
8-
COMPRESSOR_DEBUG=False
2+
FLASK_DEBUG=False
3+
SECRET_KEY=randomstringofcharacters

.flake8

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[flake8]
2+
select = E9,F63,F7,F82
3+
exclude = .git,.github,__pycache__,.pytest_cache,.venv,logs,creds
4+
max-line-length = 120

.github/workflows/pythonapp.yml

+20-22
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,30 @@ name: Python application
55

66
on:
77
push:
8-
branches: [ master ]
8+
branches: [master]
99
pull_request:
10-
branches: [ master ]
10+
branches: [master]
1111

1212
jobs:
1313
build:
14-
1514
runs-on: ubuntu-latest
1615

1716
steps:
18-
- uses: actions/checkout@v2
19-
- name: Set up Python 3.9
20-
uses: actions/setup-python@v2
21-
with:
22-
python-version: 3.9
23-
- name: Install dependencies
24-
run: |
25-
python -m pip install --upgrade pip
26-
pip install flake8 pytest
27-
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28-
- name: Lint with flake8
29-
run: |
30-
# stop the build if there are Python syntax errors or undefined names
31-
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
32-
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
33-
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
34-
- name: Test with pytest
35-
run: |
36-
pytest
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.10"
21+
cache: "pip" # caching pip dependencies
22+
23+
- name: Install dependencies
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install flake8 pytest
27+
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
28+
29+
- name: Lint with flake8
30+
run: |
31+
# stop the build if there are Python syntax errors or undefined names
32+
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
33+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
34+
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ $(VIRTUAL_ENV):
3232

3333
.PHONY: run
3434
run: env
35-
$(LOCAL_PYTHON) -m gunicorn -w 4 wsgi:app
35+
$(LOCAL_PYTHON) -m gunicorn -w 4 wsgi:app
3636

3737
.PHONY: install
3838
install: env

README.md

+6-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Flask Blueprint Tutorial
22

3-
![Python](https://img.shields.io/badge/Python-v^3.10-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a)
4-
![Flask](https://img.shields.io/badge/Flask-v2.2.2-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
5-
![Flask-Assets](https://img.shields.io/badge/Flask--Assets-v2.0-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
3+
![Python](https://img.shields.io/badge/Python-v3.10-blue.svg?logo=python&longCache=true&logoColor=white&colorB=5e81ac&style=flat-square&colorA=4c566a)
4+
![Flask](https://img.shields.io/badge/Flask-v3.0.0-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
5+
![Flask-Assets](https://img.shields.io/badge/Flask--Assets-v2.1.0-blue.svg?longCache=true&logo=flask&style=flat-square&logoColor=white&colorB=5e81ac&colorA=4c566a)
6+
![Gunicorn](https://img.shields.io/badge/Gunicorn-v21.2.0-blue.svg?longCache=true&logo=gunicorn&style=flat-square&logoColor=white&colorB=a3be8c&colorA=4c566a)
67
![GitHub Last Commit](https://img.shields.io/github/last-commit/google/skia.svg?style=flat-square&colorA=4c566a&colorB=a3be8c&logo=GitHub)
78
[![GitHub Issues](https://img.shields.io/github/issues/hackersandslackers/flask-blueprint-tutorial.svg?style=flat-square&colorA=4c566a&logo=GitHub&colorB=ebcb8b)](https://github.com/hackersandslackers/flask-blueprint-tutorial/issues)
89
[![GitHub Stars](https://img.shields.io/github/stars/hackersandslackers/flask-blueprint-tutorial.svg?style=flat-square&colorA=4c566a&logo=GitHub&colorB=ebcb8b)](https://github.com/hackersandslackers/flask-blueprint-tutorial/stargazers)
@@ -24,12 +25,8 @@ Get set up locally in two steps:
2425
Replace the values in **.env.example** with your values and rename this file to **.env**:
2526

2627
* `ENVIRONMENT`: The environment in which to run your application (either `development` or `production`).
27-
* `FLASK_APP`: Entry point of your application; should be `wsgi.py`.
28+
* `FLASK_DEBUG`: Set to `True` to enable Flask's debug mode (default to `False` in prod).
2829
* `SECRET_KEY`: Randomly generated string of characters used to encrypt your app's data.
29-
* `LESS_BIN` *(optional for static assets)*: Path to your local LESS installation via `which lessc`.
30-
* `ASSETS_DEBUG` *(optional)*: Debug asset creation and bundling in `development`.
31-
* `LESS_RUN_IN_DEBUG` *(optional)*: Debug LESS while in `development`.
32-
* `COMPRESSOR_DEBUG` *(optional)*: Debug asset compression while in `development`.
3330

3431
*Remember never to commit secrets saved in .env files to Github.*
3532

@@ -40,7 +37,7 @@ Get up and running with `make run`:
4037
```shell
4138
git clone https://github.com/hackersandslackers/flask-blueprint-tutorial.git
4239
cd flask-blueprint-tutorial
43-
make run
40+
make deploy
4441
```
4542

4643
-----

config.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Class-based Flask app configuration."""
2-
from os import environ, path
2+
from os import environ, path, system
33

44
from dotenv import load_dotenv
55

@@ -11,22 +11,24 @@ class Config:
1111
"""Configuration from environment variables."""
1212

1313
# General Config\
14-
ENVIRONMENTS = environ.get("ENVIRONMENT")
14+
ENVIRONMENT = environ.get("ENVIRONMENT")
1515

1616
# Flask Config
1717
SECRET_KEY = environ.get("SECRET_KEY")
1818
FLASK_DEBUG = environ.get("FLASK_DEBUG")
1919
FLASK_APP = "wsgi.py"
2020

21-
# Flask-Assets
22-
LESS_BIN = environ.get("LESS_BIN")
23-
ASSETS_DEBUG = False
24-
LESS_RUN_IN_DEBUG = False
25-
2621
# Static Assets
2722
STATIC_FOLDER = "static"
2823
TEMPLATES_FOLDER = "templates"
2924
COMPRESSOR_DEBUG = False
3025

26+
# Flask-Assets
27+
LESS_BIN = system("which lessc")
28+
ASSETS_DEBUG = False
29+
LESS_RUN_IN_DEBUG = False
30+
if ENVIRONMENT == "development" and LESS_BIN is None:
31+
raise ValueError("Application running in `development` mode cannot create assets without `lessc` installed.")
32+
3133
# Hardcoded data
3234
PRODUCT_DATA_FILEPATH = f"{BASE_DIR}/data/products.json"

flask_blueprint_tutorial/assets.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
from flask_assets import Bundle
44

55

6-
def compile_static_assets(assets):
7-
"""Create stylesheet bundles."""
6+
def compile_static_assets(assets: Bundle) -> Bundle:
7+
"""
8+
Create CSS stylesheet bundles from .less files.
9+
10+
:param Bundle assets: Static asset bundle.
11+
12+
:returns: Bundle
13+
"""
814
assets.auto_build = True
915
assets.debug = False
1016
common_style_bundle = Bundle(
@@ -35,7 +41,7 @@ def compile_static_assets(assets):
3541
assets.register("home_style_bundle", home_style_bundle)
3642
assets.register("profile_style_bundle", profile_style_bundle)
3743
assets.register("product_style_bundle", product_style_bundle)
38-
if app.config["ENVIRONMENTS"] == "development":
44+
if app.config["ENVIRONMENT"] == "development":
3945
common_style_bundle.build()
4046
home_style_bundle.build()
4147
profile_style_bundle.build()

flask_blueprint_tutorial/home/home.py

+18-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@
1010

1111

1212
@home_blueprint.route("/", methods=["GET"])
13-
def home():
14-
"""Render application Homepage."""
13+
def home() -> str:
14+
"""
15+
Serve `Home` page template.
16+
17+
:returns: str
18+
"""
1519
products = fetch_products(app)
1620
return render_template(
1721
"index.jinja2",
@@ -23,8 +27,12 @@ def home():
2327

2428

2529
@home_blueprint.route("/about", methods=["GET"])
26-
def about():
27-
"""Render static `about` page."""
30+
def about() -> str:
31+
"""
32+
Serve `About` page template.
33+
34+
:returns: str
35+
"""
2836
return render_template(
2937
"index.jinja2",
3038
title="About",
@@ -34,8 +42,12 @@ def about():
3442

3543

3644
@home_blueprint.route("/contact", methods=["GET"])
37-
def contact():
38-
"""Render page."""
45+
def contact() -> str:
46+
"""
47+
Serve `Contact` page template.
48+
49+
:returns: str
50+
"""
3951
return render_template(
4052
"index.jinja2",
4153
title="Contact",

flask_blueprint_tutorial/products/products.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@
1010

1111

1212
@product_bp.route("/products/<int:product_id>/", methods=["GET"])
13-
def product_page(product_id):
14-
"""Product description page."""
15-
products_json = app.config["FLASK_ENV"]
13+
def product_page(product_id: int) -> str:
14+
"""
15+
Product detail page for a given product ID.
16+
17+
:params int product_id: Unique product ID.
18+
19+
:returns: str
20+
"""
1621
product = fetch_products(app)[product_id]
1722
return render_template(
1823
"products.jinja2",

flask_blueprint_tutorial/profile/profile.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@
99

1010

1111
@profile_blueprint.route("/profile", methods=["GET"])
12-
def user_profile():
13-
"""Logged-in user profile page."""
12+
def user_profile() -> str:
13+
"""
14+
Logged-in user profile page.
15+
16+
:returns: str
17+
"""
1418
user = fake.simple_profile()
1519
job = fake.job()
1620
return render_template(

0 commit comments

Comments
 (0)