Track B · Tutorial 2

Python Authentication, Testing & Deployment

Chapter 25 · Backend Specialization
~3 hours Advanced JWT · pytest · Heroku · Docker

Overview

This tutorial extends your Python backend with authentication (JWT), testing with pytest, and deployment strategies. You will secure your APIs, write comprehensive tests, and deploy to Heroku or Docker.

Why this matters: Real‑world APIs must be secure and reliable. Testing ensures quality, and deployment makes your application accessible to users.

1. Django Authentication (JWT)

Use djangorestframework-simplejwt for JWT authentication.

pip install djangorestframework-simplejwt
# settings.py INSTALLED_APPS = [ ... 'rest_framework', 'rest_framework_simplejwt', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), }
# urls.py from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView urlpatterns = [ path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ]
# Protect a view from rest_framework.permissions import IsAuthenticated from rest_framework.views import APIView class ProtectedView(APIView): permission_classes = [IsAuthenticated] def get(self, request): return Response({'message': 'You are authenticated!'})

2. FastAPI Authentication (JWT)

FastAPI uses python-jose and passlib for JWT.

pip install python-jose[cryptography] passlib[bcrypt]
from fastapi import Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer from jose import JWTError, jwt from passlib.context import CryptContext from datetime import datetime, timedelta SECRET_KEY = "your-secret-key" ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 30 pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token") def create_access_token(data: dict): to_encode = data.copy() expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) to_encode.update({"exp": expire}) return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM) def get_current_user(token: str = Depends(oauth2_scheme)): try: payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username = payload.get("sub") if username is None: raise HTTPException(status_code=401, detail="Invalid token") return username except JWTError: raise HTTPException(status_code=401, detail="Invalid token")
# Protect an endpoint @app.get("/protected") async def protected_route(current_user: str = Depends(get_current_user)): return {"message": f"Hello {current_user}"}

3. Testing with pytest

pytest is the standard testing framework for Python. Use it to write unit, integration, and API tests.

pip install pytest pytest-django pytest-asyncio httpx

Django Test Example

# tests.py from django.test import TestCase from rest_framework.test import APIClient class ProductAPITestCase(TestCase): def setUp(self): self.client = APIClient() def test_get_products(self): response = self.client.get('/products/') self.assertEqual(response.status_code, 200)

FastAPI Test Example

from fastapi.testclient import TestClient from main import app client = TestClient(app) def test_get_products(): response = client.get("/products") assert response.status_code == 200

4. Deployment (Heroku / Docker)

Heroku (Django)

# requirements.txt gunicorn django djangorestframework psycopg2 # Procfile web: gunicorn myapi.wsgi

Docker (FastAPI)

# Dockerfile FROM python:3.10 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
docker build -t myapi . docker run -p 8000:8000 myapi

Quiz

Question 1

Which Django library is used for JWT authentication?

  • django-jwt
  • djangorestframework-simplejwt
  • django-oauth
  • django-auth
Show answer
B. djangorestframework-simplejwt.

Question 2

Which FastAPI dependency extracts the JWT token from the request?

  • JWTBearer
  • OAuth2PasswordBearer
  • AuthBearer
  • TokenDependency
Show answer
B. OAuth2PasswordBearer.

Question 3

Which testing library is recommended for Python backend testing?

  • unittest
  • pytest
  • nose
  • doctest
Show answer
B. pytest (most widely used and feature‑rich).

Exercises

Exercise 1

Add JWT authentication to the Django Product API. Protect the POST, PUT, and DELETE endpoints.

Sample answer
  • Add permission_classes = [IsAuthenticated] to the ProductViewSet.
  • Add JWT URL endpoints (/api/token/, /api/token/refresh/).
  • Test with `Authorization: Bearer <token>` header.

Exercise 2

Write a pytest test for the FastAPI /products endpoint that checks the response status and data structure.

Sample answer
from fastapi.testclient import TestClient from main import app client = TestClient(app) def test_get_products(): response = client.get("/products") assert response.status_code == 200 assert isinstance(response.json(), list) if len(response.json()) > 0: assert "name" in response.json()[0] assert "price" in response.json()[0]

Homework

Homework 1

Containerize your Django or FastAPI application with Docker. Write a Dockerfile and docker-compose.yml with a PostgreSQL database.

Sample answer

docker-compose.yml:

version: '3.8' services: db: image: postgres:14 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: mydb ports: - "5432:5432" app: build: . ports: - "8000:8000" depends_on: - db

Mini‑Project

E‑Commerce API with Auth & Testing

Build a complete e‑commerce API with:

  • User registration and login (JWT)
  • Product CRUD (authenticated)
  • Shopping cart endpoints
  • Order creation
  • pytest tests for all endpoints
  • Docker deployment
Sample outline
  • Django: Use AbstractUser for custom user model.
  • Models: Product, Cart, CartItem, Order, OrderItem
  • Permissions: IsAuthenticated for all except product list/detail
  • Tests: Test user registration, login, protected endpoints, cart operations
  • Deployment: Docker with Gunicorn and PostgreSQL

Tutorial Summary

You learned to secure Python APIs with JWT authentication, write comprehensive tests with pytest, and deploy applications using Docker and Heroku. You now have a complete production‑ready workflow for Python backend development.

Key takeaway: Security, testing, and deployment are essential pillars of professional backend development. Automate your testing and deployment pipelines for reliability.