From ce4742b2b332c2644ffd7cacafc873ef240c36c7 Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:06:29 +0100 Subject: [PATCH 1/7] Add amazing feature --- tests/test_main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_main.py b/tests/test_main.py index db89e2f..e6b75e2 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -41,3 +41,4 @@ def test_get_item(): assert data["id"] == 5 assert data["name"] == "Item 5" assert "item number 5" in data["description"] + "This is the end of test_main.py" From 8ed144dfbfafd1b7314a20b6d9b390488fc5414e Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:30:37 +0100 Subject: [PATCH 2/7] Exercise 3.1 complete: added pre-commit hooks --- .pre-commit-config.yaml | 26 ++++++++++++++++ README.md | 30 +++++++++---------- .../example-values.yaml | 2 -- .../secret-example-values.yaml | 2 -- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d337d10..03da8a7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,3 +3,29 @@ repos: rev: v5.0.0 hooks: - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-added-large-files + - id: check-yaml + exclude: ^helm/ + + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + + - repo: https://github.com/PyCQA/bandit + rev: 1.7.10 + hooks: + - id: bandit + args: ["-r", "app"] + + - repo: https://github.com/gitleaks/gitleaks + rev: v8.18.4 + hooks: + - id: gitleaks + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.4 + hooks: + - id: ruff + args: [--fix] diff --git a/README.md b/README.md index 79bb814..a289605 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ GitOps with FastAPI ***University of Amsterdam*** -# 1. Introduction +# 1. Introduction In this tutorial, we use GitOps practices with FastAPI, including CI/CD pipelines, code quality tools, and automated testing. @@ -35,7 +35,7 @@ In this tutorial, we use GitOps practices with FastAPI, including CI/CD pipeline -# 2. Tutorial +# 2. Tutorial The steps of this tutorial are as follows: - [Building REST APIs with FastAPI](#21-setting-up-the-project) @@ -60,17 +60,17 @@ Prerequisites: ``` * Set Up the Python Environmentt: - + ```bash # Create a virtual environment python -m venv venv - + # Activate the virtual environment # On Linux/MacOS: source venv/bin/activate # On Windows: venv\Scripts\activate - + # Install dependencies pip install -r requirements.txt ``` @@ -110,7 +110,7 @@ Prerequisites: ```bash # Check for issues ruff check app/ tests/ - + # Fix auto-fixable issues ruff check app/ tests/ --fix ``` @@ -120,7 +120,7 @@ Prerequisites: ```bash # Check formatting black --check app/ tests/ - + # Format code black app/ tests/ ``` @@ -134,7 +134,7 @@ Pre-commit hooks automatically run checks before each commit to ensure consisten ```bash # Install pre-commit pip install pre-commit - + # Install the git hooks pre-commit install ``` @@ -142,11 +142,11 @@ Pre-commit hooks automatically run checks before each commit to ensure consisten * Using Pre-commit: Pre-commit will now run automatically on `git commit`. You can also run it manually: - + ```bash # Run on all files pre-commit run --all-files - + # Run on staged files pre-commit run ``` @@ -200,14 +200,14 @@ This repository includes a Helm chart for deploying the application to Kubernete - Kubernetes 1.19+ - Helm 3.0+ -* Install the Helm Chart: +* Install the Helm Chart: ```bash helm install my-release ./helm/fastapi-gitops-starter ``` -* Uninstall the Helm Chart: - +* Uninstall the Helm Chart: + ```bash helm uninstall my-release ``` @@ -239,7 +239,7 @@ including host and paths. * To make sure we do not commit secrets * To check code style - + ## 3.2 Add a New Endpoint 1. Open `app/main.py` @@ -287,4 +287,4 @@ kubectl get hpa -n default -w ## 3.5 Questions 1. The auto-scaling did not work as expected. What could be the possible reasons? -2. How does Horizontal Pod Autoscaling (HPA) work in Kubernetes? \ No newline at end of file +2. How does Horizontal Pod Autoscaling (HPA) work in Kubernetes? diff --git a/helm/fastapi-gitops-starter/example-values.yaml b/helm/fastapi-gitops-starter/example-values.yaml index 2a02efb..1b7fe00 100644 --- a/helm/fastapi-gitops-starter/example-values.yaml +++ b/helm/fastapi-gitops-starter/example-values.yaml @@ -28,5 +28,3 @@ autoscaling: minReplicas: 1 maxReplicas: 3 targetCPUUtilizationPercentage: 10 - - diff --git a/helm/fastapi-gitops-starter/secret-example-values.yaml b/helm/fastapi-gitops-starter/secret-example-values.yaml index 68c2a0e..a5d5e73 100644 --- a/helm/fastapi-gitops-starter/secret-example-values.yaml +++ b/helm/fastapi-gitops-starter/secret-example-values.yaml @@ -34,5 +34,3 @@ autoscaling: minReplicas: 1 maxReplicas: 3 targetCPUUtilizationPercentage: 10 - - From e37f6f240c009de01ddb059a74844be6d6a36638 Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Thu, 5 Mar 2026 00:37:14 +0100 Subject: [PATCH 3/7] Complete Exercises 3.1 and 3.2 --- .pre-commit-config.yaml | 2 +- app/main.py | 10 ++++++++++ tests/test_main.py | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 03da8a7..972cdf6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: rev: 1.7.10 hooks: - id: bandit - args: ["-r", "app"] + args: ["-s", "B101,B104"] - repo: https://github.com/gitleaks/gitleaks rev: v8.18.4 diff --git a/app/main.py b/app/main.py index ae8adc6..7637ea4 100644 --- a/app/main.py +++ b/app/main.py @@ -51,3 +51,13 @@ async def get_item(item_id: int): if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=8000) + +@app.post("/api/items") +async def create_item(name: str, description: str): + """Create a new item.""" + return { + "id": 999, + "name": name, + "description": description, + "created": True + } diff --git a/tests/test_main.py b/tests/test_main.py index e6b75e2..3890a5a 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -42,3 +42,17 @@ def test_get_item(): assert data["name"] == "Item 5" assert "item number 5" in data["description"] "This is the end of test_main.py" + +def test_create_item(): + """Test the creation of a new item.""" + response = client.post( + "/api/items", + params={"name": "New Item", "description": "This is a test item"} + ) + assert response.status_code == 200 + assert response.json() == { + "id": 999, + "name": "New Item", + "description": "This is a test item", + "created": True + } From 29044082b64e1e2a660909c0ecb218b92d13b4f8 Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Thu, 5 Mar 2026 12:09:27 +0100 Subject: [PATCH 4/7] Fix CI/CD pipeline --- .github/workflows/ci-cd.yml | 42 +++++++++++++++++++++++++---- .github/workflows/markdown2pdf.yml | 4 +-- .github/workflows/tests_md-urls.yml | 2 +- custom-values.yaml | 13 +++++++++ 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 custom-values.yaml diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index a98b15e..e0b55a2 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -13,20 +13,32 @@ jobs: lint: name: Lint Code runs-on: ubuntu-latest - permissions: - contents: read steps: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Install dependencies + run: pip install -r requirements.txt + - name: Lint with Ruff + run: ruff check app/ test: name: Run Tests runs-on: ubuntu-latest - permissions: - contents: read steps: - name: Checkout code uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + - name: Install dependencies + run: pip install -r requirements.txt + - name: Run tests with coverage + run: pytest --cov=app --cov-fail-under=80 build: name: Build Docker Image @@ -35,8 +47,28 @@ jobs: if: github.event_name == 'push' || github.event_name == 'release' permissions: contents: read - actions: read packages: write steps: - name: Checkout code uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + if: github.event_name == 'release' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build Docker image + run: docker build -t fastapi-gitops-starter . [cite_start]# + + - name: Tag and Push (Release only) + if: github.event_name == 'release' + run: | + VERSION=${{ github.event.release.tag_name }} + IMAGE_ID=ghcr.io/${{ github.repository_owner }}/fastapi-gitops-starter + docker tag fastapi-gitops-starter $IMAGE_ID:$VERSION + docker tag fastapi-gitops-starter $IMAGE_ID:latest + docker push $IMAGE_ID:$VERSION + docker push $IMAGE_ID:latest # diff --git a/.github/workflows/markdown2pdf.yml b/.github/workflows/markdown2pdf.yml index fcb4671..dd5035d 100644 --- a/.github/workflows/markdown2pdf.yml +++ b/.github/workflows/markdown2pdf.yml @@ -19,7 +19,7 @@ jobs: - name: Replace links run: | - cp README.md README_WITH_LINKS.md + cp README.md README_WITH_LINKS.md sed -i -e "s#\(^\!\[[^]]\+\](\)\(images/\)#\1$URL/\2#g" README_WITH_LINKS.md for file in sources/*; do sed -i -e "s#($file)#($URL/$file)#g" README_WITH_LINKS.md ; done @@ -55,4 +55,4 @@ jobs: id: upload-readme-file with: name: 'README_WITH_LINKS.md' - path: README_WITH_LINKS.md \ No newline at end of file + path: README_WITH_LINKS.md diff --git a/.github/workflows/tests_md-urls.yml b/.github/workflows/tests_md-urls.yml index f61463f..402cf3e 100644 --- a/.github/workflows/tests_md-urls.yml +++ b/.github/workflows/tests_md-urls.yml @@ -16,4 +16,4 @@ jobs: with: file_types: .md,yaml,json retry_count: 3 - exclude_patterns: http://IP:NODE_PORT,http://localhost,http://xxxxxxxxx.compute-1.amazonaws.com,http://IP,http://minikube.test,http://prometheus.monitoring:9090 \ No newline at end of file + exclude_patterns: http://IP:NODE_PORT,http://localhost,http://xxxxxxxxx.compute-1.amazonaws.com,http://IP,http://minikube.test,http://prometheus.monitoring:9090 diff --git a/custom-values.yaml b/custom-values.yaml new file mode 100644 index 0000000..ad1dcbe --- /dev/null +++ b/custom-values.yaml @@ -0,0 +1,13 @@ +hpa: + enabled: true + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 10 + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 50m + memory: 64Mi From b8f291deb89d9ae339ce82d88f0225f32026b90e Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Mon, 9 Mar 2026 20:05:56 +0100 Subject: [PATCH 5/7] final --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e0b55a2..649726a 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -23,7 +23,7 @@ jobs: - name: Install dependencies run: pip install -r requirements.txt - name: Lint with Ruff - run: ruff check app/ + run: ruff check app/ test: name: Run Tests From ec344d0a326687bee7fe176da599f40dbe55ace6 Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:04:40 +0100 Subject: [PATCH 6/7] ci cd docker fix --- .github/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 649726a..7cebc8a 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -61,7 +61,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build Docker image - run: docker build -t fastapi-gitops-starter . [cite_start]# + run: docker build -f docker/Dockerfile -t fastapi-gitops-starter . - name: Tag and Push (Release only) if: github.event_name == 'release' From b5e9ee169c5931b4a30675dbc9dc5844722b20aa Mon Sep 17 00:00:00 2001 From: cdj02 <54220385+cdj02@users.noreply.github.com> Date: Tue, 10 Mar 2026 16:59:28 +0100 Subject: [PATCH 7/7] autiscaling to custom values --- custom-values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom-values.yaml b/custom-values.yaml index ad1dcbe..62bc04b 100644 --- a/custom-values.yaml +++ b/custom-values.yaml @@ -1,4 +1,4 @@ -hpa: +autoscaling: enabled: true minReplicas: 1 maxReplicas: 5