Skip to content
Open

Lab03 #2448

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Python CI

on:
[push, pull_request]

permissions:
contents: read

jobs:

test:
name: Lint & Tests
runs-on: ubuntu-latest
timeout-minutes: 10

strategy:
fail-fast: true

steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r app_python/requirements.txt
pip install pytest ruff

- name: Lint
run: ruff check .

- name: Run tests
run: pytest

- name: Setup Snyk
uses: snyk/actions/setup@master

- name: Run Snyk
run: snyk test --file=app_python/requirements.txt
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}


docker:
name: Build & Push Docker
needs: test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Set version (CalVer)
id: version
run: |
echo "VERSION=$(date +'%Y.%m')" >> $GITHUB_OUTPUT

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./app_python
file: ./app_python/Dockerfile
push: true
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/app_python:2026.02
${{ secrets.DOCKERHUB_USERNAME }}/app_python:latest
8 changes: 8 additions & 0 deletions app_python/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.venv
venv
__pycache__
.git
.gitignore
.env
*.pyc
.idea
156 changes: 156 additions & 0 deletions app_python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
node_modules

# Output
.output
.vercel
.netlify
.wrangler
.svelte-kit
/build

# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*

# OS
.DS_Store
Thumbs.db

# Env
.env.*
!.env.example
!.env.test

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
coverage

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

.pdm.toml
.pdm-python
.pdm-build/

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# JetBrains IDEs
.idea/
16 changes: 16 additions & 0 deletions app_python/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:3.13-slim

WORKDIR /app

RUN adduser --disabled-password --gecos "" appuser

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

RUN chown -R appuser:appuser /app

USER appuser

CMD ["python", "app.py"]
76 changes: 76 additions & 0 deletions app_python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
## Overview
This API contains two endpoints:
1. Getting information about the system
2. Getting the health status of the API itself

## Prerequisites
```
python==3.13.5
uvicorn==0.40.0
pydantic==2.12.5
fastapi==0.128.0
```

## Installation

```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```

## Running

```bash
python app.py
# Or with custom config
PORT=8080 python app.py
```

## API Endpoints

```
GET / - Service and system information
GET /health - Health check
```

## Configuration

| Variable | Description | Type | Default | Example |
| -------- | -------------------------------------- | ------- | --------- |-------------|
| `HOST` | Host address the application binds to | string | `0.0.0.0` | `127.0.0.1` |
| `PORT` | Port number the application listens on | integer | `5000` | `8000` |
| `DEBUG` | Enables debug mode | boolean | `False` | `True` |

## Docker

1. Building the image
example:
```bash
docker build -t <image_name>:<tag> <context>
```

to build our service used:
```bash
docker duild -t devops-info-service:latest .
```
2. Running a container
example:
```bash
docker run <options> <image_name>
```

to run our service used:
```bash
docker run -d -p 5000:5000 devops-info-service
```

3. Pulling from Docker Hub example:
```bash
docker pull <repo_name>
```

to pull our repo used:
```bash
docker pull th1ef/devops-info-service:latest
```
22 changes: 22 additions & 0 deletions app_python/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from config import DEBUG, PORT, HOST
from routes import health_router, root_router
from logger_config import setup_logger

setup_logger()
app = FastAPI(debug=DEBUG)
for router in [health_router, root_router]:
app.include_router(router=router)

app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

if __name__ == "__main__":
uvicorn.run(app=app, port=PORT, host=HOST)
5 changes: 5 additions & 0 deletions app_python/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import os

HOST = os.getenv("HOST", "0.0.0.0")
PORT = int(os.getenv("PORT", 5000))
DEBUG = os.getenv("DEBUG", "False").lower() == "true"
Loading