Skip to main content

📚 FastAPI Training Assignments

Product Catalog Service - Practical Exercises

Course: Building High-Performance APIs with FastAPI Version: 1.0.0 Last Updated: 2025-12-24


🎯 Project Overview

Business Context

You are tasked with building a Product Catalog Service - a RESTful API for an e-commerce company's product management system. The system needs to meet the following requirements:

  • User Management: Registration, login, role assignment
  • Product Management: CRUD operations with validation
  • Security: JWT authentication, password hashing
  • Documentation: Auto-generated API docs

Technical Requirements

ComponentTechnology
FrameworkFastAPI 0.104+
Python3.11+
ORMSQLAlchemy 2.0
DatabasePostgreSQL or SQLite
MigrationsAlembic
ValidationPydantic 2.0

Project Structure

mono-src/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI application
│ ├── api/ # Route handlers
│ │ ├── __init__.py
│ │ ├── auth.py
│ │ ├── products.py
│ │ └── deps.py # Dependencies
│ ├── config/
│ │ └── settings.py # Configuration
│ ├── database/
│ │ └── database.py # DB connection
│ ├── models/ # SQLAlchemy models
│ │ ├── user.py
│ │ └── product.py
│ ├── repositories/ # Data access layer
│ │ ├── base.py
│ │ ├── user_repository.py
│ │ └── product_repository.py
│ ├── schemas/ # Pydantic schemas
│ │ ├── user.py
│ │ └── product.py
│ ├── services/ # Business logic
│ │ ├── auth_service.py
│ │ └── product_service.py
│ └── utils/
│ └── security.py # JWT, hashing
├── alembic/ # Migrations
├── tests/ # Unit tests
├── requirements.txt
├── alembic.ini
└── .env


📝 Assignment 01: Foundation & Inputs

Unit 1 - Sessions 1-2

🎯 Learning Objectives

  • Understand the basic structure of a FastAPI application
  • Create endpoints with path and query parameters
  • Explore automatic OpenAPI documentation

📖 Business Requirements

Scenario

The company needs a basic API to check system status and provide service information. This API will be used by:

  • DevOps team: Monitoring health status
  • Frontend team: Displaying API version information
  • Integration team: Checking connectivity

✅ Required Tasks

Task 1.1: Project Setup (10 points)

Requirements:

  1. Create a virtual environment and install dependencies
  2. Create directory structure according to project structure
  3. Create requirements.txt file with necessary packages
  4. Create .env.example file with configuration template

Acceptance Criteria:

  • Virtual environment is functional
  • FastAPI import works without errors
  • Directory structure is correct

Task 1.2: Root Endpoint (15 points)

Business Logic:

When a user accesses the root endpoint, the system must return introduction information regarding the API including:

  • Service name
  • Current version
  • Path to documentation

Technical Requirements:

EndpointMethodResponse Code
/GET200

Response Format:

{
"message": "Welcome to Product Catalog Service API",
"version": "1.0.0",
"docs": "/docs",
"redoc": "/redoc"
}

Acceptance Criteria:

  • Endpoint returns correct JSON format
  • Status code is 200
  • Content-Type is application/json

Task 1.3: Health Check Endpoint (15 points)

Business Logic:

The Health check endpoint is used by load balancers and monitoring tools to check if the service is operational. This endpoint needs to:

  • Be always available (no authentication required)
  • Fast response (< 100ms)
  • Return status information and metadata

Technical Requirements:

EndpointMethodResponse Code
/healthGET200

Response Format:

{
"status": "healthy",
"service": "Product Catalog Service",
"version": "1.0.0",
"timestamp": "2025-12-24T10:00:00Z"
}

Acceptance Criteria:

  • Endpoint accessible without authentication
  • Response time < 100ms
  • Timestamp is in ISO 8601 format

Task 1.4: Products List with Query Parameters (20 points)

Business Logic:

The API needs to support pagination for the product list. This is a critical feature because:

  • The database may contain millions of products
  • Frontend needs to load data page by page
  • Reduce load on server and network

Technical Requirements:

EndpointMethodQuery Params
/productsGETskip, limit

Query Parameters:

ParamTypeDefaultConstraints
skipinteger0>= 0
limitinteger101-100

Acceptance Criteria:

  • Default values applied when params are not passed
  • Validation for negative values (skip) and out of range (limit)
  • Automatic type conversion (string → int)

Task 1.5: Product Detail with Path Parameter (15 points)

Business Logic:

Each product has a unique ID. The API needs an endpoint to retrieve product details by ID.

Technical Requirements:

EndpointMethodPath Param
/products/{product_id}GETproduct_id (int)

Acceptance Criteria:

  • Path parameter validated as integer
  • Returns 422 if product_id is not a number
  • Response contains product_id in body (temporarily)

🌟 Bonus Tasks

Bonus 1.1: Request Metadata (5 points)

Guideline: Create endpoint /debug/request-info returning request metadata like headers, client IP, user-agent. Research FastAPI Request object.

Bonus 1.2: Environment-based Response (5 points)

Guideline: Root endpoint displays additional environment field (development/staging/production) based on environment variable.

Bonus 1.3: API Versioning (10 points)

Guideline: Implement URL-based API versioning (/api/v1/...). Create router prefix and organize code to support multiple versions.


📊 Rubric - Assignment 01

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
Project Setup (10pts)Complete structure, standard compliant, has .env.exampleCorrect structure, missing 1-2 filesBasic structure, missing many filesFailed to create project
Root Endpoint (15pts)Correct response format, has description in docsCorrect response, missing docs descriptionResponse missing fieldsEndpoint not working
Health Check (15pts)Full fields, dynamic timestamp, < 100msFull fields, static timestampMissing 1-2 fieldsEndpoint not working
Query Params (20pts)Complete validation, default values, error handlingWorks correctly, basic validationMissing validationPagination not implemented
Path Params (15pts)Type validation, proper error responseWorks correctlyMissing validationEndpoint not working
Code Quality (10pts)Clean code, type hints, docstringsFull type hintsReadable codeMessy code
Documentation (15pts)Complete Swagger UI with descriptionsSwagger UI present but missing descriptionsBasic Swagger UINo documentation

Total: 100 points Bonus: 20 points


📝 Assignment 02: Data Modeling with Pydantic

Unit 2 - Sessions 3-4

🎯 Learning Objectives

  • Define Pydantic schemas for validation
  • Use Field constraints and validators
  • Understand response_model filtering
  • Handle validation errors

📖 Business Requirements

Scenario

Product Catalog needs strict input data validation to ensure:

  • Data integrity: Product price must be positive, name cannot be empty
  • Security: Prevent invalid data injection
  • User experience: Return clear error messages

✅ Required Tasks

Task 2.1: User Schemas (20 points)

Business Logic:

The system has 2 types of user data:

  1. Input data (UserCreate): Username and password during registration
  2. Output data (UserResponse): User info returned to client (does NOT contain password)

Validation Rules:

FieldRules
usernameRequired, 3-50 characters, alphanumeric + underscore
passwordRequired, min 6 characters

Acceptance Criteria:

  • UserCreate validates input according to rules
  • UserResponse does not contain password field
  • Validation error returns 422 with error details

Task 2.2: Product Schemas (25 points)

Business Logic:

Products in the system need the following information:

  • Required: name, price, quantity
  • Optional: description
  • Automatic: id, timestamps

Schemas to create:

SchemaPurpose
ProductCreateInput when creating product
ProductUpdateInput when updating (all optional)
ProductResponseOutput returned to client

Validation Rules:

FieldTypeRules
namestringRequired, 1-100 chars
descriptionstringOptional, max 500 chars
pricedecimalRequired, > 0, max 2 decimal places
quantityintegerRequired, >= 0

Business Constraints:

  • Price cannot be negative or 0 (free products use a different field)
  • Quantity can be 0 (out of stock) but cannot be negative
  • Name cannot contain only spaces

Acceptance Criteria:

  • All validation rules are implemented
  • ProductUpdate allows partial update
  • Error messages descriptive and helpful

Task 2.3: POST Endpoint with Request Body (20 points)

Business Logic:

Implement endpoint to create a new product. This endpoint:

  • Receives data from request body (JSON)
  • Validates according to ProductCreate schema
  • Returns ProductResponse (temporarily not saving to DB)

Technical Requirements:

EndpointMethodRequest BodyResponse
/productsPOSTProductCreateProductResponse

Response Codes:

CodeCondition
201Created successfully
422Validation error

Acceptance Criteria:

  • Request body is parsed and validated
  • Response uses response_model
  • Status code 201 for success

Task 2.4: Token Schema (10 points)

Business Logic:

Prepare schema for JWT token response (will be used in Assignment 05).

Schema:

Token:
- access_token: string (JWT token)
- token_type: string (default "bearer")

Acceptance Criteria:

  • Token schema defined
  • Default value for token_type

Task 2.5: Enhanced Documentation (10 points)

Business Logic:

API documentation needs to be clear so frontend team and third-parties can integrate. Each endpoint needs:

  • Concise summary
  • Detailed description
  • Example request/response
  • Possible error responses

Acceptance Criteria:

  • All endpoints have summary and description
  • Schemas have field descriptions
  • Examples are provided in docs

🌟 Bonus Tasks

Bonus 2.1: Custom Validators (10 points)

Guideline: Implement custom validator for password (must contain at least 1 uppercase, 1 lowercase, 1 number). Use @field_validator decorator.

Bonus 2.2: Nested Models (10 points)

Guideline: Create ProductWithCategory schema with nested Category model. Category has id and name.

Bonus 2.3: Computed Fields (5 points)

Guideline: Add computed field is_in_stock (boolean) in ProductResponse, automatically calculated from quantity > 0.


📊 Rubric - Assignment 02

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
User Schemas (20pts)Complete validation, password excludedCorrect validation, missing 1 ruleBasic schemasFailed to create schemas
Product Schemas (25pts)All rules, clear error messagesCorrect validation, generic error messagesMissing 1-2 validationsSchemas do not validate
POST Endpoint (20pts)201 response, proper response_modelWorks correctly, different codeResponse incorrect formatEndpoint error
Token Schema (10pts)Complete with defaultsCorrect schemaMissing defaultNo schema
Documentation (10pts)Comprehensive with examplesHas descriptionsBasic descriptionsNo descriptions
Code Quality (15pts)Clean, organized, type hintsFull type hintsReadable codeMessy code

Total: 100 points Bonus: 25 points


📝 Assignment 03: Database Setup

Unit 3 - Sessions 5-6

🎯 Learning Objectives

  • Setup SQLAlchemy with FastAPI
  • Create database models with SQLAlchemy 2.0
  • Use Alembic for migrations
  • Understand database session management

📖 Business Requirements

Scenario

Product Catalog needs persistent storage. Requirements:

  • Data is not lost when restarting server
  • Support multiple database types (PostgreSQL for production, SQLite for development)
  • Schema changes are tracked and reversible

✅ Required Tasks

Task 3.1: Database Configuration (15 points)

Business Logic:

Database connection needs:

  • Configurable via environment variables
  • Connection pooling for performance
  • Automatic reconnection when connection drops

Configuration needed:

VariableDescriptionExample
DATABASE_URLConnection stringpostgresql://user:pass@localhost:5432/catalog

Acceptance Criteria:

  • Database URL from environment variable
  • Support both PostgreSQL and SQLite
  • Connection pool configured (for PostgreSQL)

Task 3.2: User Model (20 points)

Business Logic:

User model stores authentication info:

  • Username unique for login
  • Password hashed (not stored in plaintext)
  • Track creation and update time of account

Model Definition:

ColumnTypeConstraints
idIntegerPrimary Key, Auto-increment
usernameString(50)Unique, Not Null, Indexed
hashed_passwordString(255)Not Null
is_activeBooleanDefault True, Not Null
created_atDateTimeServer default now()
updated_atDateTimeAuto-update on change

Acceptance Criteria:

  • Model uses SQLAlchemy 2.0 style
  • Index on username column
  • Timestamps automatically managed

Task 3.3: Product Model (20 points)

Business Logic:

Product model stores product information. Note:

  • Price uses Numeric type to avoid floating point errors
  • Quantity can be 0 (out of stock)

Model Definition:

ColumnTypeConstraints
idIntegerPrimary Key, Auto-increment
nameString(100)Not Null, Indexed
descriptionString(500)Nullable
priceNumeric(10,2)Not Null
quantityIntegerDefault 0, Not Null
created_atDateTimeServer default now()
updated_atDateTimeAuto-update on change

Acceptance Criteria:

  • Price uses Numeric type
  • Default values set
  • Timestamps work correctly

Task 3.4: Alembic Setup (20 points)

Business Logic:

Database migrations allow:

  • Track schema changes in version control
  • Apply changes incrementally
  • Rollback if errors occur
  • Sync schema between environments

Tasks:

  1. Initialize Alembic in project
  2. Configure env.py to read models
  3. Generate initial migration
  4. Apply migration to create tables

Acceptance Criteria:

  • alembic init completed
  • env.py configured correctly
  • Initial migration generated
  • Tables created after alembic upgrade head

Task 3.5: Database Session Dependency (15 points)

Business Logic:

Each request needs a separate database session. Session must:

  • Be created when request starts
  • Automatically close when request ends
  • Handle errors gracefully

Acceptance Criteria:

  • get_db dependency function created
  • Session yielded and cleaned up in finally
  • Dependency injectable in routes

🌟 Bonus Tasks

Bonus 3.1: Soft Delete (10 points)

Guideline: Add is_deleted and deleted_at columns. Products are not actually deleted but marked as deleted. Queries default to filtering out deleted items.

Bonus 3.2: Audit Fields (10 points)

Guideline: Add created_by and updated_by columns to track user making changes. Implement base mixin class for reusability.

Bonus 3.3: Database Seeding (5 points)

Guideline: Create script to seed initial data (sample users and products). Useful for development and testing.


📊 Rubric - Assignment 03

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
DB Config (15pts)Pooling, env vars, both DB typesEnv vars, 1 DB typeHardcoded configCannot connect
User Model (20pts)All columns, constraints, indexesMissing 1-2 constraintsBasic modelModel errors
Product Model (20pts)Numeric price, all columnsMissing constraintsBasic modelModel errors
Alembic (20pts)Full setup, migration worksMigration works, minor issuesPartial setupAlembic not working
Session Dependency (15pts)Proper yield/cleanup, injectableWorks but cleanup issuesBasic implementationNot working
Code Organization (10pts)Clean separation, imports correctMinor organization issuesCode in wrong placesMessy structure

Total: 100 points Bonus: 25 points


📝 Assignment 04: CRUD & Dependency Injection

Unit 4 - Sessions 7-8

🎯 Learning Objectives

  • Implement Repository Pattern
  • Use Dependency Injection in FastAPI
  • Build complete CRUD operations
  • Handle database exceptions

📖 Business Requirements

Scenario

Backend team needs to implement business logic layer separated from route handlers. This allows:

  • Testability: Mock dependencies in tests
  • Reusability: Repositories can be used in multiple services
  • Maintainability: Business logic centralized in one place

✅ Required Tasks

Task 4.1: Base Repository (15 points)

Business Logic:

Generic repository provides basic CRUD operations for every model. Use Python Generics for type-safety.

Methods to implement:

MethodParametersReturnDescription
createobj_data: dictTCreate new record
get_by_idid: intOptional[T]Get by ID
get_allskip: int, limit: intList[T]Get list with pagination
updateid: int, obj_data: dictOptional[T]Update record
deleteid: intboolDelete record

Acceptance Criteria:

  • Generic type parameter T used
  • All methods implemented correctly
  • Return types correct

Task 4.2: User Repository (15 points)

Business Logic:

User repository extends BaseRepository with specific methods:

  • Find user by username (for authentication)
  • Check username existence (for registration)

Additional Methods:

MethodParametersReturnDescription
get_by_usernameusername: strOptional[User]Find user by username
exists_by_usernameusername: strboolCheck username exists

Acceptance Criteria:

  • Inherits from BaseRepository
  • Custom methods implemented
  • Query only active users (is_active=True)

Task 4.3: Product Repository (15 points)

Business Logic:

Product repository with methods:

  • Search by product name
  • Filter products in stock

Additional Methods:

MethodParametersReturnDescription
search_by_namename: strList[Product]Search LIKE %name%
get_in_stockskip, limitList[Product]Only products with quantity > 0

Acceptance Criteria:

  • Inherits from BaseRepository
  • Search case-insensitive
  • Pagination works with custom queries

Task 4.4: Product Service (15 points)

Business Logic:

Service layer contains business logic, orchestrates between repository and validation:

  • Validate business rules (e.g., no duplicate names)
  • Transform data between schemas and models
  • Handle complex operations

Methods:

MethodDescription
create_productValidate and create new product
get_productGet product, raise exception if not found
update_productPartial update with validation
delete_productDelete product
list_productsGet list with pagination

Acceptance Criteria:

  • Service uses repository (does not query directly)
  • Business validation in service
  • Proper exception handling

Task 4.5: CRUD Endpoints (30 points)

Business Logic:

Implement complete CRUD for Products:

EndpointMethodDescriptionResponse Code
GET /productsGETList with pagination200
GET /products/{id}GETGet single product200, 404
POST /productsPOSTCreate product201, 422
PUT /products/{id}PUTUpdate product200, 404, 422
DELETE /products/{id}DELETEDelete product204, 404

Error Handling:

ScenarioResponse
Product not found404 with message
Validation error422 with details
Server error500 with generic message

Acceptance Criteria:

  • All endpoints work correctly
  • Proper status codes
  • Error responses have clear messages

🌟 Bonus Tasks

Bonus 4.1: Search & Filter API (10 points)

Guideline: Extend GET /products with multiple query params: search (name), min_price, max_price, in_stock (boolean). Combine filters in query.

Bonus 4.2: Sorting (10 points)

Guideline: Add sort_by and sort_order query params. Support sort by price, name, created_at. Order: asc/desc.

Bonus 4.3: Bulk Operations (15 points)

Guideline: Implement POST /products/bulk to create multiple products at once. Handle partial failures (some succeed, some fail).


📊 Rubric - Assignment 04

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
Base Repository (15pts)Generic, all methods, type hintsAll methods, no genericsMissing 1-2 methodsNot working
User Repository (15pts)Custom methods, proper queriesWorks, query issuesBasic implementationNot working
Product Repository (15pts)Search, filter, paginationMissing 1 featureBasic implementationNot working
Product Service (15pts)Business logic, validation, DIWorks, missing validationBasic implementationNot working
CRUD Endpoints (30pts)All working, proper codes, errorsMinor issuesSome endpoints brokenMost not working
Code Quality (10pts)Clean, DI pattern, separationGood structureAcceptablePoor structure

Total: 100 points Bonus: 35 points


📝 Assignment 05: Authentication (AuthN)

Unit 5 - Sessions 9-10

🎯 Learning Objectives

  • Implement password hashing with bcrypt
  • Create and validate JWT tokens
  • Build authentication endpoints
  • Understand OAuth2 Password Flow

📖 Business Requirements

Scenario

The system needs authentication to:

  • Identity: Determine who the user is
  • Security: Protect sensitive operations
  • Audit: Track who performed actions

Authentication flow:

  1. User registers with username/password
  2. Password is hashed before saving
  3. User logs in to receive JWT token
  4. Token is sent in subsequent requests

✅ Required Tasks

Task 5.1: Password Hashing Utilities (20 points)

Business Logic:

Passwords must NEVER be stored in plaintext. Use bcrypt because:

  • Automatically generates salt
  • Configurable work factor
  • Widely tested and trusted

Functions to implement:

FunctionParametersReturnDescription
get_password_hashpassword: strstrHash password
verify_passwordplain: str, hashed: strboolVerify password

Security Requirements:

  • Salt generated for each hash
  • Hash output is string (storable)
  • Timing-safe comparison

Acceptance Criteria:

  • bcrypt used
  • Same password produces different hashes (salt)
  • Verify works with correct password
  • Verify fails with wrong password

Task 5.2: JWT Token Utilities (20 points)

Business Logic:

JWT token contains:

  • sub (subject): username or user_id
  • exp (expiration): expiration time
  • Signed with secret key

Functions to implement:

FunctionParametersReturnDescription
create_access_tokendata: dictstrCreate JWT token
decode_access_tokentoken: strOptional[str]Decode and validate

Configuration:

SettingDescriptionDefault
SECRET_KEYSigning keyRequired, min 32 chars
ALGORITHMJWT algorithmHS256
ACCESS_TOKEN_EXPIRE_MINUTESToken lifetime30

Acceptance Criteria:

  • Token contains correct claims
  • Expired tokens rejected
  • Invalid tokens return None
  • Secret key from environment

Task 5.3: Auth Service (15 points)

Business Logic:

Auth service handles:

  • User registration with duplicate check
  • User authentication (login)
  • Token generation

Methods:

MethodDescription
register_userCreate user with hashed password
authenticate_userVerify credentials, return user
loginAuthenticate and return token

Acceptance Criteria:

  • Duplicate username returns error
  • Password hashed before save
  • Authentication verifies password
  • Login returns token

Task 5.4: Registration Endpoint (15 points)

Business Logic:

User registration endpoint:

  • Validate input (username, password rules)
  • Check duplicate username
  • Hash password
  • Create user
  • Return user info (no password)

API Specification:

EndpointMethodRequestSuccessError
/registerPOSTUserCreate201 + UserResponse400, 422

Acceptance Criteria:

  • Successful registration returns 201
  • Duplicate username returns 400
  • Password NOT in response
  • User is active by default

Task 5.5: Login Endpoint (20 points)

Business Logic:

Login endpoint implements OAuth2 Password Flow:

  • Accepts form data (not JSON) per OAuth2 spec
  • Returns JWT token
  • Standard error for invalid credentials

API Specification:

EndpointMethodContent-TypeSuccessError
/loginPOSTapplication/x-www-form-urlencoded200 + Token401

Form Fields:

  • username: string
  • password: string

Error Response:

{
"detail": "Incorrect username or password"
}

Security Note: Error message MUST NOT specify if username or password is incorrect (prevent enumeration).

Acceptance Criteria:

  • Form data accepted (not JSON)
  • Valid credentials return token
  • Invalid credentials return 401
  • Generic error message

🌟 Bonus Tasks

Bonus 5.1: Refresh Tokens (15 points)

Guideline: Implement refresh token flow. Access token short-lived (15 min), refresh token longer (7 days). Endpoint /refresh to get new access token.

Bonus 5.2: Password Strength Validation (10 points)

Guideline: Validate password strength: min 8 chars, uppercase, lowercase, number, special char. Return specific error for each failed rule.

Bonus 5.3: Account Lockout (10 points)

Guideline: Lock account after 5 failed login attempts. Track failed_attempts and locked_until in User model. Auto unlock after 15 minutes.


📊 Rubric - Assignment 05

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
Password Hashing (20pts)bcrypt, salt, timing-safeWorks correctlyBasic implementationNot secure
JWT Utilities (20pts)All claims, expiry, validationMissing expiry checkBasic implementationNot working
Auth Service (15pts)All methods, proper errorsMissing 1 methodBasic implementationNot working
Registration (15pts)All validations, proper responseMinor issuesWorks but issuesNot working
Login (20pts)OAuth2 flow, form data, errorsWorks, minor issuesJSON instead of formNot working
Security (10pts)No plaintext, generic errors, env varsMinor security issuesSome security issuesMajor security issues

Total: 100 points Bonus: 35 points


📝 Assignment 06: Authorization (AuthZ)

Unit 6 - Sessions 11-12

🎯 Learning Objectives

  • Implement OAuth2PasswordBearer
  • Create authentication dependencies
  • Protect endpoints with dependencies
  • Implement Role-Based Access Control

📖 Business Requirements

Scenario

After authentication is in place, authorization is needed to control:

  • Who can do what
  • Public endpoints vs Protected endpoints
  • Role-based permissions (user vs admin)

Access Control Matrix:

EndpointAnonymousUserAdmin
GET /products
GET /products/{id}
POST /products
PUT /products/{id}
DELETE /products/{id}

✅ Required Tasks

Task 6.1: OAuth2PasswordBearer Setup (10 points)

Business Logic:

OAuth2PasswordBearer:

  • Defines token URL for Swagger UI
  • Extracts token from Authorization header
  • Format: Bearer <token>

Acceptance Criteria:

  • oauth2_scheme configured with tokenUrl="login"
  • Swagger UI shows Authorize button
  • Token extracted from header

Task 6.2: Get Current User Dependency (25 points)

Business Logic:

Dependency chain:

  1. Extract token from header (oauth2_scheme)
  2. Decode and validate token
  3. Get user from database
  4. Return user object

Error Handling:

ScenarioResponse
No token401 Unauthorized
Invalid token401 Unauthorized
Expired token401 Unauthorized
User not found401 Unauthorized
User inactive401 Unauthorized

Response Headers:

WWW-Authenticate: Bearer

Acceptance Criteria:

  • Dependency returns User object
  • All error scenarios handled
  • Proper 401 response with header
  • Active user check included

Task 6.3: Get Current Active User (10 points)

Business Logic:

Wrapper dependency to ensure user is active. Can be used for routes specifically requiring active user.

Acceptance Criteria:

  • Depends on get_current_user
  • Check is_active flag
  • Return 401 if inactive

Task 6.4: Protect Product Endpoints (25 points)

Business Logic:

Apply authentication to modification endpoints:

  • POST /products: Require authenticated user
  • PUT /products/{id}: Require authenticated user
  • DELETE /products/{id}: Require authenticated user (will add admin check)

Implementation Pattern:

  • Add current_user dependency to routes
  • Routes automatically protected
  • Swagger UI shows lock icon

Acceptance Criteria:

  • POST /products requires auth
  • PUT /products/{id} requires auth
  • DELETE /products/{id} requires auth
  • GET endpoints remain public
  • 401 returned without token

Task 6.5: Role-Based Access Control (20 points)

Business Logic:

Implement role system:

  1. Add role column to User model
  2. Default role: "user"
  3. Admin role: "admin"
  4. Delete operation requires admin

Model Update:

ColumnTypeDefault
roleString(20)"user"

Role Check Dependency:

  • Create dependency factory for role checking
  • Returns 403 Forbidden if insufficient permissions
  • Reusable for different roles

Acceptance Criteria:

  • Role column added via migration
  • Default role is "user"
  • DELETE /products/{id} requires admin
  • 403 returned for insufficient role
  • Other endpoints work with user role

🌟 Bonus Tasks

Bonus 6.1: Permission-Based Access (15 points)

Guideline: Instead of roles, implement permissions (can_create_product, can_delete_product, etc.). User has list of permissions. More granular than roles.

Bonus 6.2: Resource Ownership (10 points)

Guideline: Track creator of each product (created_by field). Users can only update/delete products they created. Admins can modify all.

Bonus 6.3: API Key Authentication (10 points)

Guideline: Alternative authentication with API keys for service-to-service communication. Header: X-API-Key. Separate from JWT auth.


📊 Rubric - Assignment 06

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
OAuth2 Setup (10pts)Swagger integration, proper configWorks, minor issuesBasic setupNot working
Get Current User (25pts)All error cases, proper responsesMissing 1-2 casesBasic implementationNot working
Active User Check (10pts)Proper dependency chainWorksBasic checkNot working
Protected Endpoints (25pts)All routes protected correctlyMinor issuesSome routes unprotectedMost not working
RBAC (20pts)Migration, role check, 403Missing migrationBasic role fieldNot implemented
Security (10pts)Proper 401/403, no leaksMinor issuesSome security gapsMajor issues

Total: 100 points Bonus: 35 points


📝 Assignment 07: Testing & Middleware

Unit 7 - Sessions 13-14

🎯 Learning Objectives

  • Write unit tests with Pytest
  • Use TestClient for API testing
  • Implement CORS middleware
  • Create custom exception handlers

📖 Business Requirements

Scenario

Before production deployment, we need:

  • Test coverage: Ensure code works as expected
  • CORS config: Allow frontend access from different origins
  • Error handling: Consistent error responses
  • Quality assurance: Prevent regressions

✅ Required Tasks

Task 7.1: Test Setup (15 points)

Business Logic:

Test environment needs:

  • Separate test database (do not affect real data)
  • Fresh database for each test (isolation)
  • Fixtures for common setup

Test Structure:

tests/
├── __init__.py
├── conftest.py # Shared fixtures
├── test_health.py # Health check tests
├── test_auth.py # Auth tests
└── test_products.py # Product tests

Fixtures needed:

  • client: TestClient instance
  • db_session: Test database session
  • test_user: Pre-created user for auth tests
  • auth_headers: Headers with valid JWT

Acceptance Criteria:

  • Test database separate from development
  • Database reset between tests
  • Fixtures reusable across tests

Task 7.2: Health Check Tests (10 points)

Test Cases:

TestDescriptionExpected
test_health_checkGET /health200, status="healthy"
test_root_endpointGET /200, has version

Acceptance Criteria:

  • Both tests pass
  • Response content verified
  • Status codes checked

Task 7.3: Authentication Tests (25 points)

Test Cases:

TestDescriptionExpected
test_register_successValid registration201, user created
test_register_duplicateSame username twice400, error message
test_register_invalid_passwordShort password422, validation error
test_login_successValid credentials200, token returned
test_login_wrong_passwordInvalid password401, error
test_login_nonexistent_userUnknown username401, error

Acceptance Criteria:

  • All test cases implemented
  • Tests are independent (do not depend on order)
  • Assertions meaningful and specific

Task 7.4: Product CRUD Tests (25 points)

Test Cases:

TestDescriptionExpected
test_get_products_emptyList when empty200, []
test_get_products_with_dataList with data200, list of products
test_get_product_successGet existing200, product data
test_get_product_not_foundGet non-existing404
test_create_product_successCreate with auth201, product created
test_create_product_unauthorizedCreate without auth401
test_create_product_invalidInvalid data422
test_update_product_successUpdate with auth200, updated
test_delete_product_successDelete with admin204
test_delete_product_forbiddenDelete with user role403

Acceptance Criteria:

  • All CRUD operations tested
  • Auth scenarios covered
  • Error cases tested
  • Data integrity verified

Task 7.5: CORS Middleware (10 points)

Business Logic:

Frontend at http://localhost:3000 needs to access API at http://localhost:8000. CORS middleware:

  • Allow specified origins
  • Allow credentials (cookies, auth headers)
  • Handle preflight requests

Configuration:

SettingValue
allow_originsFrom environment variable
allow_credentialsTrue
allow_methods["*"]
allow_headers["*"]

Acceptance Criteria:

  • CORS headers in responses
  • Origins configurable via env
  • Preflight OPTIONS handled

Task 7.6: Custom Exception Handler (15 points)

Business Logic:

Standardize error responses across API:

  • Consistent JSON structure
  • Include request path
  • Hide internal errors in production

Error Response Format:

{
"error": true,
"message": "Human readable message",
"detail": "Technical detail (dev only)",
"path": "/products/999"
}

Exception Handlers:

  • HTTPException handler (customize format)
  • ValidationError handler (422)
  • Generic Exception handler (500)

Acceptance Criteria:

  • All errors follow same format
  • Path included in response
  • 500 errors don't leak internals

🌟 Bonus Tasks

Bonus 7.1: Test Coverage Report (10 points)

Guideline: Configure pytest-cov to generate coverage report. Target: > 80% coverage. Add coverage badge to README.

Bonus 7.2: Integration Tests (15 points)

Guideline: Test complete flows: register → login → create product → update → delete. Verify data persistence across requests.

Bonus 7.3: Request Logging Middleware (10 points)

Guideline: Log each request: method, path, status code, duration. Structured logging with JSON format. Useful for debugging and monitoring.

Bonus 7.4: Rate Limiting (15 points)

Guideline: Implement rate limiting middleware. Limit: 100 requests/minute per IP. Return 429 Too Many Requests when exceeded.


📊 Rubric - Assignment 07

CriteriaExcellent (100%)Good (80%)Satisfactory (60%)Needs Improvement (40%)
Test Setup (15pts)Fixtures, isolation, cleanWorks, minor issuesBasic setupNot working
Health Tests (10pts)Both pass, good assertionsPass with weak assertionsOne test onlyNot working
Auth Tests (25pts)All 6 cases, thoroughMissing 1-2 casesBasic tests onlyMost failing
Product Tests (25pts)All 10 cases, thoroughMissing 2-3 casesHalf implementedMost failing
CORS (10pts)Configurable, all headersWorks, hardcodedBasic CORSNot working
Exception Handler (15pts)Consistent format, all typesMissing 1 handlerBasic handlerNot working

Total: 100 points Bonus: 50 points


📊 Final Grade Calculation

Assignment Weights

AssignmentWeightMax PointsBonus
Assignment 0110%10020
Assignment 0210%10025
Assignment 0315%10025
Assignment 0420%10035
Assignment 0515%10035
Assignment 0615%10035
Assignment 0715%10050
Total100%700225

Grade Scale

GradePercentageDescription
A+95-100%Exceptional, all bonuses
A90-94%Excellent
A-85-89%Very Good
B+80-84%Good
B75-79%Above Average
B-70-74%Average
C+65-69%Below Average
C60-64%Minimum Pass
F< 60%Fail

Bonus Points

Bonus points are added to the final score, maximum 10% extra credit.


📚 Resources

Official Documentation

Security

Testing


Document Version: 1.0.0 Created: 2025-12-24 Author: Training Team