From ea40810fa3b1e6bd4b6b55daed0b815823ffc5dd Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 09:58:30 +0100 Subject: [PATCH 1/8] feat: flake8 config file --- tox.ini | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tox.ini diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..28473b1 --- /dev/null +++ b/tox.ini @@ -0,0 +1,4 @@ +[flake8] +extend-ignore = E203 +exclude = .git,__pycache__,.venv +max-complexity = 10 \ No newline at end of file From 528da91ed49a44b1d02d720bb0917df3c5a18305 Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:03:42 +0100 Subject: [PATCH 2/8] feat: CI/CD for flake8 linting, warning : this commit is a test for the execution of the pipeline --- .gitlab-ci.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1029ba4..c0412a4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,13 +1,16 @@ -stages: - - build +default: + image: python:3.9 +stages: + - lint + - build build job: stage: build script: - cd src - - apt-get update -qy - - apt-get install -y python3-dev python3-pip python3.12-venv curl + # - apt-get update -qy + # - apt-get install -y python3-dev python3-pip python3.12-venv curl - python3 -V # - pip3 install --break-system-packages -r requirements.txt - curl -sSL https://pdm-project.org/install-pdm.py | python3 - @@ -22,11 +25,18 @@ build job: - export FLASK_APP=app - pdm run pytest tests --cov --cov-report term --cov-report html - artifacts: paths: - src/htmlcov/ +lint job: + stage: lint + dependencies: [] + script: + - python3 -m pip install flake8 + - flake8 src/ + allow_failure: true # Linter can fail, fixing it is for now outside of the projects scope + pages: stage: build dependencies: From 3d6abfa9bc7f7613b672162b9858ff06b6719148 Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:11:40 +0100 Subject: [PATCH 3/8] fix: linter errors over app.py [no ci] --- src/app.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/app.py b/src/app.py index 782c882..2f76b3b 100644 --- a/src/app.py +++ b/src/app.py @@ -18,12 +18,8 @@ from flask import request, Flask, url_for, render_template, redirect import operators import json -from dotenv import load_dotenv import os - - - __author__ = 'Michael Mäder' __date__ = "2025-03-10" __version__ = "0.5" @@ -40,7 +36,8 @@ A little web application that offers API calls for arithmetic operations # creation of the Flask application app = Flask(__name__) -app.config['SECRET_KEY'] = os.environ.get('FLASK_SECRET_KEY') # super secure key against CSRF attacks +# super secure key against CSRF attacks +app.config['SECRET_KEY'] = os.environ.get('FLASK_SECRET_KEY') # global variable containing the name of the login user global_data = {'username': 'no_user'} @@ -51,18 +48,19 @@ global_data = {'username': 'no_user'} def plus_one(): try: x = int(request.args.get('x', 1)) - except: + except ValueError: return json.dumps({"error": "Type error"}) return json.dumps({'x': operators.addition(x, 1)}) + # addition route, the parameters will be passed with 'x' and 'y' @app.route('/add') def plus_y(): try: x = int(request.args.get('x', 1)) y = int(request.args.get('y', 1)) - except: + except ValueError: return json.dumps({"error": "Type error"}) return json.dumps({'result': operators.addition(x, y)}) @@ -73,7 +71,7 @@ def multiply_y(): try: x = int(request.args.get('x', 1)) y = int(request.args.get('y', 1)) - except: + except ValueError: return json.dumps({"error": "Type error"}) return json.dumps({'result': operators.multiplication(x, y)}) @@ -84,7 +82,7 @@ def division_y(): try: x = int(request.args.get('x', 1)) y = int(request.args.get('y', 1)) - except: + except ValueError: return json.dumps({"error": "Type error"}) return json.dumps({'result': operators.division(x, y)}) From 83d70c4fc57e265892627ee405e4e0cfa7d0237a Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:12:30 +0100 Subject: [PATCH 4/8] fix: linter errors over operators.py [no ci] --- src/operators.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/operators.py b/src/operators.py index 8aa5a40..5168248 100644 --- a/src/operators.py +++ b/src/operators.py @@ -23,17 +23,17 @@ __email__ = "michael.maeder@hefr.ch" # file containing the operations for the calculator -# addition: returns x+y +# addition: returns x+y def addition(x, y): return x+y -# subtraction: returns x-y +# subtraction: returns x-y def subtraction(x, y): return x-y -# multiplication: returns x*y +# multiplication: returns x*y def multiplication(x, y): return x*y @@ -42,6 +42,6 @@ def multiplication(x, y): # returns None if the divisor is zero # the result might be of float type def division(x, y): - if y==0: + if y == 0: return None return x/y From 89e66a8b58697de3516250dc9906569d0250ed55 Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:14:08 +0100 Subject: [PATCH 5/8] fix: linter errors over conftest.py [no ci] --- src/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index ed58e1a..ed50b44 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -5,7 +5,7 @@ from app import app # the client here allow to use the app without running in live server -# see https://flask.palletsprojects.com/en/2.0.x/testing/#sending-requests-with-the-test-client +# see https://flask.palletsprojects.com/en/2.0.x/testing/#sending-requests-with-the-test-client # noqa: E501 @pytest.fixture def client(): app.config['TESTING'] = True From 570a0d3ceadd96e13494e2ba5b449d975e6d2e42 Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:16:35 +0100 Subject: [PATCH 6/8] fix: changed the amount of chars in a single line to 120 --- tox.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 28473b1..8000b14 100644 --- a/tox.ini +++ b/tox.ini @@ -1,4 +1,5 @@ [flake8] extend-ignore = E203 exclude = .git,__pycache__,.venv -max-complexity = 10 \ No newline at end of file +max-complexity = 10 +max-line-length = 120 From df1db2fd973eab86d508b55719d705a4f943121d Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:18:15 +0100 Subject: [PATCH 7/8] fix: linter errors over test_api.py --- src/tests/test_api.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/tests/test_api.py b/src/tests/test_api.py index cceefb7..486ddbc 100644 --- a/src/tests/test_api.py +++ b/src/tests/test_api.py @@ -17,7 +17,6 @@ from urllib.parse import urlencode import json -import pytest __author__ = 'Michael Mader' __date__ = "2023-03-12" @@ -27,12 +26,12 @@ __email__ = "michael.maeder@hefr.ch" def call(client, path, params): """calling function that simulates an API webcall of a specific function/route - + Args: client: this is the client object used by pytest to 'simulate' the API without running the webserver path: route of the API to use params: GET parameter that are passed to the function - + Returns: json: the result of the client call """ @@ -40,50 +39,59 @@ def call(client, path, params): response = client.get(url) return json.loads(response.data.decode('utf-8')) + # increment test 1 def test_plus_one1(client): result = call(client, '/inc', {'x': 2}) assert result['x'] == 3 + # increment test 1 def test_plus_one2(client): result = call(client, '/inc', {'x': -2}) assert result['x'] == -1 + # adding test with negative value def test_plus_y(client): result = call(client, '/add', {'x': -2, 'y': 7}) assert result['result'] == 5 + # multiplication test def test_multiply(client): result = call(client, '/mul', {'x': -2, 'y': 7}) assert result['result'] == -14 + # division test def test_division(client): result = call(client, '/div', {'x': 35, 'y': 7}) assert result['result'] == 5 + # type tests def test_type_inc(client): result = call(client, '/inc', {'x': 'a'}) assert result["error"] == "Type error" + def test_type_add(client): result = call(client, '/add', {'x': 'a', 'y': 1}) assert result["error"] == "Type error" result = call(client, '/add', {'x': 1, 'y': 'a'}) assert result["error"] == "Type error" + def test_type_mul(client): result = call(client, '/mul', {'x': 'a', 'y': 1}) assert result["error"] == "Type error" result = call(client, '/mul', {'x': 1, 'y': 'a'}) assert result["error"] == "Type error" + def test_type_div(client): result = call(client, '/div', {'x': 'a', 'y': 1}) assert result["error"] == "Type error" result = call(client, '/div', {'x': 1, 'y': 'a'}) - assert result["error"] == "Type error" \ No newline at end of file + assert result["error"] == "Type error" From 9c496e73bb5c20cf4e0c81d5e8291022f7423247 Mon Sep 17 00:00:00 2001 From: "Alec.Schmidt" Date: Tue, 18 Mar 2025 10:30:19 +0100 Subject: [PATCH 8/8] chore: answer to questions [no ci] --- docs/questions-part1.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/questions-part1.md b/docs/questions-part1.md index 8a7c2db..54264b3 100644 --- a/docs/questions-part1.md +++ b/docs/questions-part1.md @@ -11,3 +11,7 @@ ## Q1.2 - It's a very bad practice. The secret key will be exposed in the codebase and can be easily accessed by anyone who has access to the codebase. This can lead to security vulnerabilities and compromise the integrity of the application. - To fix this, you can use environment variables to store the secret key. + +## Q1.3 +- A linter is a tool to statically analyse code for readability and improving code quality. It is usually executed from a standalone tool. +- It is used to check for errors, vulns, code smells or general issues but also to enforce a coding style over the whole project. \ No newline at end of file