Skip to content
Merged
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
103 changes: 95 additions & 8 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,95 @@
Written to:
/home/dewald/Workspace/personal/github/python_rest_tutorial/.github/copilot-instructions.md

Changes made:
- Expanded the project overview section with stack details
- Added repository structure, environment variables, authentication, testing, dependency management, and Postman sections — all drawn directly from the README
- Preserved the existing human-authored Code Exploration section (codegraph + understand-anything) verbatim
- Kept everything concise and terminal-readable, no invented facts
# python_rest_tutorial — Copilot Instructions

## Project Overview

Educational REST API built with Python, Flask, Docker, and MongoDB.
Stack: Flask 3.1.3, flask-restful, pymongo 4.7.2, bcrypt, PyJWT, pytest, Ruff, Docker + docker-compose.

Reference article:
https://www.dvt.co.za/news-insights/insights/item/355-restful-web-services-using-python-flask-docker-and-mongodb

## Repository Structure

web/ Flask application source (app.py) + Dockerfile
web/requirements.txt Pinned runtime and dev dependencies (includes ruff, pytest)
web/tests/ Unit tests for the Flask app
tests/ Config-level and API-contract tests
scripts/lint.sh Local lint script — mirrors CI exactly
docker-compose.yml Service definitions: web app + MongoDB
.env.example Environment variable template
pyproject.toml Ruff linting and formatting config

## Environment Variables

| Variable | Default | Description |
|------------|------------------------|----------------------------------------------------------|
| MONGO_URI | mongodb://my_db:27017/ | MongoDB connection string |
| JWT_SECRET | (required) | JWT signing secret. Must be long and random. Never commit.|

## Authentication Flow

1. Register: POST /register {"username": "...", "password": "..."}
2. Login: POST /login {"username": "...", "password": "..."} → returns {"token": "..."}
3. Protected: POST /retrieve or /save with header Authorization: Bearer <token>

Tokens expire after 1 hour. Missing/expired/tampered tokens return 401.

## Running Locally

cp .env.example .env # set JWT_SECRET
sudo docker-compose build
sudo docker-compose up
curl http://localhost:5000/hello # → "Hello World!"

## Running Tests

pip install -r web/requirements.txt
pytest -v
# Runs web/tests/ (unit) and tests/ (config + contract)

## Linting

./scripts/lint.sh # check only — same as CI
./scripts/lint.sh --fix # auto-fix then check

Ruff config is in pyproject.toml. Rules: E, F, I (pycodestyle, Pyflakes, isort).
Line length: 120. Both web/ and tests/ are in scope.

## CI Pipeline

Defined in .github/workflows/ci.yml. Two sequential jobs on every push/PR:

lint → test

lint: ruff check + ruff format --check
test: pytest -v (only runs if lint passes)

## Code Conventions

- All imports must be sorted (ruff I rules enforced in CI).
- Use insert_one / update_one (PyMongo 4.x API — not deprecated insert/update).
- JWT datetime must use timezone-aware datetimes: datetime.datetime.now(timezone.utc).
- Passwords are bcrypt-hashed — never stored in plaintext.
- All endpoints return {"status": <code>, ...} JSON bodies.

## Code Exploration

### codegraph

.codegraph/ is present. Use it first for symbol lookup and call tracing.

codegraph context "<task description>" -p .
codegraph query "<ClassName or function>" -p .
codegraph affected <changed-files> -p .
codegraph sync .

### understand-anything

.understand-anything/knowledge-graph.json is present. Use for architecture questions.

skill: understand-chat

Decision order for code tasks:
1. codegraph context — which symbols matter?
2. understand-anything — where in the architecture does this live?
3. Read raw source — only the 1-2 files that actually matter.
37 changes: 37 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI

on:
push:
branches: ["**"]
pull_request:
branches: ["**"]

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install ruff
run: pip install "ruff>=0.5.0"
- name: ruff check
run: ruff check web/ tests/
- name: ruff format check
run: ruff format --check web/ tests/

test:
name: Tests
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install -r web/requirements.txt
- name: Run tests
run: pytest -v
20 changes: 0 additions & 20 deletions .github/workflows/test.yml

This file was deleted.

76 changes: 74 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,20 +1,92 @@
# Environment variables
.env
.env.local
.env.*.local

# Python bytecode
__pycache__/
*.pyc
*.pyo
*.pyd
.Python

# Distribution / packaging
*.egg
*.egg-info/
dist/
build/
.vscode/
.idea/
eggs/
parts/
var/
sdist/
wheels/
*.whl
MANIFEST

# Virtual environments
.venv/
venv/
env/
ENV/
.virtualenv/

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

# Unit test / coverage
.pytest_cache/
.coverage
.coverage.*
htmlcov/
.tox/
.nox/
nosetests.xml
coverage.xml
*.cover

# MyPy / type checking
.mypy_cache/
.dmypy.json
dmypy.json
.pyre/
.pytype/

# Ruff / linting
.ruff_cache/

# IDEs and editors
.vscode/
.idea/
*.swp
*.swo
*~
.project
.classpath
.settings/

# macOS
.DS_Store
.AppleDouble
.LSOverride

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini

# Docker
docker-compose.override.yml

# Logs
*.log
logs/

# MongoDB data (if mounted locally)
data/

# Jupyter notebooks checkpoints
.ipynb_checkpoints/

# BEGIN workspace-orchestrator
.hermes_tmp_prompt.txt
Expand Down
41 changes: 32 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ API design, containerisation, JWT authentication, password hashing, and testing.

Reference article: https://www.dvt.co.za/news-insights/insights/item/355-restful-web-services-using-python-flask-docker-and-mongodb

Stack: Flask 2.2.5, flask-restful, pymongo, bcrypt, PyJWT, pytest, Docker + docker-compose, MongoDB.
Stack: Flask 3.1.3, flask-restful 0.3.10, pymongo 4.7.2, bcrypt 4.1.3, PyJWT >=2.8.0, pytest 9.0.3, Ruff >=0.5.0, Docker + docker-compose, MongoDB.

## Repository Structure

web/ Python application source and tests
web/requirements.txt Pinned runtime + dev dependencies
docker-compose.yml Service definitions (app + MongoDB)
web/ Flask application source (app.py) + Dockerfile
web/requirements.txt Pinned runtime + dev dependencies (includes ruff, pytest)
web/tests/ Unit tests for the Flask app
tests/ Config-level and API-contract tests
scripts/lint.sh Local lint script — mirrors CI exactly
pyproject.toml Ruff linting and formatting config
docker-compose.yml Service definitions: web app + MongoDB
.env.example Environment variable template

## Getting Started
Expand Down Expand Up @@ -61,9 +65,27 @@ Missing, expired, or tampered tokens return 401 Unauthorized.

## Running Tests

cd web
pip install -r requirements.txt
pytest
Run from the project root — pytest discovers both web/tests/ and tests/:

pip install -r web/requirements.txt
pytest -v

## Linting

The project uses Ruff (replaces flake8 + isort + black). Config is in pyproject.toml.

./scripts/lint.sh # check only — same as CI
./scripts/lint.sh --fix # auto-fix then check

## CI Pipeline

Defined in .github/workflows/ci.yml. Two sequential jobs on every push and PR:

lint → test

lint: ruff check + ruff format --check across web/ and tests/
test: pytest -v (only runs if lint passes)


## Postman

Expand All @@ -78,8 +100,9 @@ All dependencies are exact-pinned in web/requirements.txt for reproducible build
Upgrade procedure:
1. Update the version in web/requirements.txt.
2. Reinstall: pip install -r web/requirements.txt
3. Run tests: cd web && pytest
4. Commit the updated requirements.txt.
3. Run tests: pytest -v
4. Run lint: ./scripts/lint.sh
5. Commit the updated requirements.txt.

<!-- graph-tools-start -->

Expand Down
Loading
Loading