DeveloperBootstrap

Python

Python 3.12 Web Development Complete Guide

Master Python 3.12 web development with Django 5.0, FastAPI, REST APIs, PostgreSQL 16 database integration, JWT authentication, pytest testing, and Docker production deployment on Ubuntu 24.04 LTS.

What you'll learn

  • Set up a Python 3.12 development environment with virtual environments
  • Build REST APIs with Django 5.0 and Django REST Framework
  • Build async APIs with FastAPI
  • Integrate PostgreSQL 16 with both frameworks
  • Implement JWT authentication
  • Write pytest test suites with 80%+ coverage
  • Containerise and deploy with Docker

Development Environment

Bash
1# Install Python 3.12 on Ubuntu 24.04
2sudo apt update && sudo apt install -y python3.12 python3.12-venv python3-pip
3
4# Create and activate virtual environment
5python3.12 -m venv .venv
6source .venv/bin/activate   # Windows: .venv/Scripts/activate
7
8# Upgrade pip
9pip install --upgrade pip

Django 5.0 REST API

Python
1pip install django==5.0 djangorestframework psycopg2-binary
2
3# Create project and app
4django-admin startproject config .
5python manage.py startapp api
6
7# settings.py additions
8INSTALLED_APPS = [
9    ...
10    'rest_framework',
11    'api',
12]
13
14REST_FRAMEWORK = {
15    'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework_simplejwt.authentication.JWTAuthentication'],
16    'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated'],
17    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
18    'PAGE_SIZE': 20,
19}
20
21# api/serializers.py
22from rest_framework import serializers
23from .models import Course
24
25class CourseSerializer(serializers.ModelSerializer):
26    class Meta:
27        model = Course
28        fields = ['id', 'title', 'description', 'created_at']
29        read_only_fields = ['id', 'created_at']
30
31# api/views.py
32from rest_framework import viewsets
33from .models import Course
34from .serializers import CourseSerializer
35
36class CourseViewSet(viewsets.ModelViewSet):
37    queryset = Course.objects.all().order_by('-created_at')
38    serializer_class = CourseSerializer

FastAPI Async API

Python
1pip install fastapi uvicorn[standard] sqlalchemy asyncpg pydantic
2
3# main.py
4from fastapi import FastAPI, Depends, HTTPException
5from pydantic import BaseModel, EmailStr
6
7app = FastAPI(title="My API", version="1.0.0")
8
9class CourseCreate(BaseModel):
10    title: str
11    description: str
12
13class CourseResponse(CourseCreate):
14    id: int
15    model_config = {"from_attributes": True}
16
17@app.get("/courses", response_model=list[CourseResponse])
18async def list_courses(skip: int = 0, limit: int = 20, db=Depends(get_db)):
19    return await db.fetch_all("SELECT * FROM courses LIMIT $1 OFFSET $2", limit, skip)
20
21@app.post("/courses", response_model=CourseResponse, status_code=201)
22async def create_course(data: CourseCreate, db=Depends(get_db)):
23    return await db.fetch_one(
24        "INSERT INTO courses (title, description) VALUES ($1, $2) RETURNING *",
25        data.title, data.description
26    )

PostgreSQL Integration

Python
1# .env
2DATABASE_URL=postgresql://user:password@localhost:5432/mydb
3
4# Django settings.py
5import os
6DATABASES = {
7    'default': {
8        'ENGINE': 'django.db.backends.postgresql',
9        'NAME': os.environ['DB_NAME'],
10        'USER': os.environ['DB_USER'],
11        'PASSWORD': os.environ['DB_PASSWORD'],
12        'HOST': os.environ.get('DB_HOST', 'localhost'),
13        'PORT': os.environ.get('DB_PORT', '5432'),
14        'CONN_MAX_AGE': 600,
15    }
16}

JWT Authentication

Python
1pip install djangorestframework-simplejwt
2
3# settings.py
4from datetime import timedelta
5SIMPLE_JWT = {
6    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
7    'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
8    'ROTATE_REFRESH_TOKENS': True,
9    'AUTH_COOKIE': 'access_token',
10    'AUTH_COOKIE_HTTP_ONLY': True,
11    'AUTH_COOKIE_SAMESITE': 'Lax',
12}
13
14# urls.py
15from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
16urlpatterns = [
17    path('auth/login/',   TokenObtainPairView.as_view()),
18    path('auth/refresh/', TokenRefreshView.as_view()),
19]

Testing with pytest

Python
1pip install pytest pytest-django pytest-cov factory-boy
2
3# pytest.ini
4[pytest]
5DJANGO_SETTINGS_MODULE = config.settings.test
6python_files = tests.py test_*.py *_test.py
7
8# tests/test_courses.py
9import pytest
10from rest_framework.test import APIClient
11from django.contrib.auth import get_user_model
12
13User = get_user_model()
14
15@pytest.fixture
16def api_client():
17    return APIClient()
18
19@pytest.fixture
20def auth_client(db):
21    user = User.objects.create_user('[email protected]', 'securepass123')
22    client = APIClient()
23    client.force_authenticate(user=user)
24    return client
25
26@pytest.mark.django_db
27def test_list_courses(auth_client):
28    response = auth_client.get('/api/courses/')
29    assert response.status_code == 200
30    assert 'results' in response.data

Docker Deployment

DOCKERFILE
1# Dockerfile
2FROM python:3.12-slim AS base
3WORKDIR /app
4ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
5
6FROM base AS deps
7COPY requirements.txt .
8RUN pip install --no-cache-dir -r requirements.txt
9
10FROM deps AS runner
11COPY . .
12RUN adduser --disabled-password --no-create-home appuser
13USER appuser
14EXPOSE 8000
15CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]