Teaching Modern Web Development with Python

Screenshot of Django admin Diagram of an asynchronous web app Screenshot of FastAPI generated documentation

Tips for navigating the slides:

  • Press O or Escape for overview mode.
  • Visit this link for a nice printable version
  • Press the copy icon on the upper right of code blocks to copy the code

About me

Photo of Pamela smiling with an Olaf statue

Python Cloud Advocate at Microsoft

Volunteer instructor for GDI (GirlDevelopIt)

Formerly: UC Berkeley, Coursera, Khan Academy, Google

Find me online at:

Mastodon @pamelafox@fosstodon.org
Twitter @pamelafox
LinkedIn www.linkedin.com/in/pamelafox
GitHub www.github.com/pamelafox
Website pamelafox.org

Web development in 2024

A bunch of raccoon students with computers

Today we'll talk about...

  • Development environments
  • Modern web frameworks
  • Databases
  • Containerization
  • Developer tools
  • AI-Assisted coding
  • Testing
  • Cloud deployment

Choosing a language

For the frontend:

  • JavaScript or TypeScript
  • Frameworks: React, Vue, Svelte, Lit, Web Components, HTMX

For the backend:

  • Python
  • Node.js
  • Java
  • C#
  • Go
  • PHP
  • Ruby
  • Rust

Why Python?

Python is a great language for teaching web development because:

  • Many students already know Python
  • Huge ecosystem, many libraries
  • Also in data science, ML, and AI
  • Multiple popular web frameworks

Modern Python versions

Source: JetBrains Developers Survey 2023

The current version of Python is 3.12. See python.org/downloads for the latest version of Python.

Try not to stay behind more than a year. New versions are faster due to efforts of the Faster CPython team.

New versions also have better debugging messages:

		schwarzschild_blackhole = 1916
		>>> schwarschild_blackhole 
		Traceback (most recent call last): 
		  File "", line 1, in  
		NameError: name 'schwarschild_blackhole' is not defined.
		Did you mean: schwarzschild_blackhole? 

Development environments

A raccoon with a background of code

Modern dev environments

In a company, the goal of a dev environment is to make it easy for a developer to work on multiple projects, and for all developers on a particular project to have the same environment.

An good dev environment is replicable and isolated.


  • Virtual environments
  • Docker containers
  • Dev containers
  • GitHub Codespaces

Virtual environments

Python has a built-in tool for creating virtual environments:

                % python -m venv .venv
                % source .venv/bin/activate

Then you can install dependencies with pip:

                (.venv) % python -m pip install numpy
                (.venv) % python -m pip install -r requirements.txt

Virtual environments are good for isolating Python dependencies, but they do not isolate the rest of the environment.

Dev Containers

Screenshot of a Python devcontainer.json
Full devcontainer.json

Dev Containers define a complete development environment for a project, using a .devcontainer/devcontainer.json file that configures a Docker image and other settings.


  • Consistent environment
  • Easy to set up
  • Isolated from the host machine

Opening dev containers in VS Code

To use a repository that has a dev container defined, first install:

Then, open the repository in VS Code, and you will be prompted to "Reopen in Container". Select that option and wait... (First build takes time ⏱️)

Screenshot of VS Code prompt to reopen in a dev container

Opening dev containers in GitHub Codespaces

GitHub Codespaces is a cloud-based development environment that can be used to develop any GitHub repository.

If no devcontainer.json is in the repository, it will try using the default "universal" container. If a devcontainer.json is present, it will use that.

Screenshot of Code tab on GitHub repository with option to open in GitHub codespaces

Creating a dev container

Start from existing dev container definitions and modify as needed:

Learn more about dev containers: containers.dev

Python web frameworks

A raccoon summoning Python from a laptop

Modern web frameworks

Graph of Python web framework popularity
Source: JetBrains Developers Survey 2023

Python has a few modern web frameworks that are popular:

  • Flask / Quart: Lightweight, flexible
  • FastAPI: Lightweight, popular for API-first development
  • Django: Opinionated, includes database functionality


Flask is a lightweight web framework that includes routing and template rendering.

                from flask import Flask, render_template
                app = Flask(__name__)

                def hello_world():
                    return render_template('index.html')

For more functionality, bring in extensions like: Flask-SQLAlchemy for database ORM, WTForms for forms, etc.

Quart is an asynchronous version of Flask.

Sample apps: Basic Flask server, Flask + DB example


Screenshot of Django admin
Source: Django website

Django is an opinionated web framework with:

  • ORM for database access
  • Admin interface
  • Forms, templates, and views
  • Security features
  • Internationalization
  • Testing tools

Sample apps: Django quiz app


Screenshot of FastAPI generated documentation
Source: FastAPI documentation

FastAPI is an async framework for building APIs (with auto-generated documentation) based on standard Python type hints.

                from fastapi import FastAPI
                app = FastAPI()

                class Item(BaseModel):
                    name: str
                    description: Optional[str] = None
                    price: float
                async def create_item(item: Item):
                    return item

Sample apps: Simple FastAPI app, Static Maps API

The importance of async

We need async to build modern web apps that support concurrency.

A web app without async:

Diagram of a synchronous web app

A web app with async can handle new requests while waiting for an I/O op:

Diagram of an asynchronous web app

Any app with slow network requests, DB queries, or file reads can benefit.

See also: FastAPI tutorial on async

Which framework to teach?

I like to teach all of them, so students can become framework-agnostic and choose the best tool for the job.

But if you have to choose one...

  • Flask: Easy to get started, but it can get hairy when you need more functionality
  • Django: Includes everything, but it's a lot to learn at once. Good fit for very standard webapps like a blog or content site.
  • FastAPI: Easy to get started, great fit if you're building an API

Teaching materials for web frameworks

Get workshop materials for Flask, Django, and FastAPI from https://github.com/pamelafox/python-web-apps

👩🏼‍🏫 Attend our live streams covering those workshops in June.


A raccoon with a background of data

Database options

Graph of  database popularity
Source: JetBrains Developers Survey 2023

Two main types of databases:

  • Relational databases: PostgreSQL, MySQL, SQLite, MSSQL, ...
  • NoSQL databases: MongoDB, Redis, ...


PostgreSQL is a popular open-source relational database that supports JSON, XML, and other data types.

                CREATE TABLE cities (
                    name            varchar(80),
                    location        point
                INSERT INTO cities VALUES ('San Francisco', '(-194.0, 53.0)');
                SELECT name FROM cities WHERE location <@ circle '((0,0), 300)';

There are many popular extensions for PostgreSQL like PostGIS for geospatial data and pgvector for vector similarity search.

Python libraries for PostgreSQL: psycopg (driver), SQLAlchemy (ORM)

Playgrounds: PostgreSQL playground, pgvector playground

Use an ORM!

ORMs (Object-Relational Mappers) like SQLAlchemy and Django's ORM make it easier to work with databases and protect against SQL injection attacks.

Example code using SQLAlchemy ORM:

                class BlogPost(Base):
                    __tablename__ = "blog_post"
                    id: Mapped[int] = mapped_column(primary_key=True)
                    title: Mapped[str] = mapped_column(String(30))
                    content: Mapped[str]

                b = BlogPost(title="My first post", content="Hello world")

Playgrounds: PostgreSQL playground, pgvector playground


MongoDB is a popular source-available NoSQL database that stores data in JSON-like documents.

                post = {
                    "author": "Mike",
                    "text": "My first blog post!",
                    "tags": ["mongodb", "python", "pymongo"]

Python libraries for MongoDB: pymongo (driver), beanie (ODM)


Redis is an open-source in-memory data structure store that can be used as a database, cache, or message broker.

                import redis
                r = redis.Redis(host='localhost', port=6379, db=0)
                r.set('session-id-123', 'user-id-456')

Python libraries for Redis: redis-py (driver)

Which database to teach?

My personal preference is to teach PostgreSQL, because it can be used in so many different types of applications, and most students do not need the extreme scalability of NoSQL databases or the fast caching abilities of Redis.

Also, SQL is a good skill to have, given the popularity of SQL databases.

Teaching materials for databases

Get workshop materials for "Databases" from https://github.com/pamelafox/python-web-apps

👩🏼‍🏫 Attend our live stream covering the workshop in June.

Containerization with Docker

A raccoon with a background of containers

Docker overview

The Docker engine runs multiple Docker containers, where each container is an isolated environment.

Diagram of two Docker containers running on top of one Docker engine running on top of an Operating System on top of Hardware

Docker images

A container image is a software package that includes everything needed to run an application.
A container is a running instance of a container image.

Diagram of two Docker images, one with Python/PostgreSQL/Django, the other with Ruby/MySQL/Rails, and one running Django container

Dockerfile for Flask

A Dockerfile is a text file that contains instructions for building a Docker image.

                FROM python:3.11

                WORKDIR /code

                COPY requirements.txt .
                RUN pip3 install -r requirements.txt

                COPY . .

                EXPOSE 50505

                ENTRYPOINT ["gunicorn", "-c", "gunicorn.conf.py", "app:app"]

Why use Docker?

Local development:

  • Consistent environment
  • Isolated from host machine
  • Easy to set up


  • Easy to scale
  • Supported by cloud providers
  • Portable across cloud providers/platforms

Teaching materials for Docker

Get workshop materials for "Containerization" from https://github.com/pamelafox/python-web-apps

👩🏼‍🏫 Attend our live stream covering the workshop in June.

Check out container.training for more materials.

Coding assistance

Screenshot of Bit the raccoon coworking with friends

Modern coding assistance

Modern coding assistance tools can help students write better code, faster, and can make coding more accessible.

  • Intellisense: Pylance
  • Debugger: Debugpy
  • Linters: Ruff, Pylance
  • Formatters: Ruff, Black


Intellisense is an IDE feature that provides code completions, parameter info, quick info, and member lists.

In VS Code use the Python extension which includes the Pylance extension.

Screenshot of Python code in VS Code with intellisense IntelliSense and autocomplete for Python code


Debuggers help you step through code, set breakpoints, and inspect variables.

In VS Code, use the Python extension which includes the Debugpy extension.

Screenshot of Python code in VS Code with debugger


A linter identifies code style issues as well as possible bugs. The most common linter is flake8 but there's a new faster linter called ruff.

Run ruff on a file or folder:

                % python -m ruff check .

In VS Code, use the Ruff extension for in-IDE linting.

Screenshot of Python code in VS Code with ruff error pop-up


A formatter automatically formats code to a consistent style. The most popular formatter is black, which is PEP 8 compliant and fairly opinionated.

Run black on a file or folder:

                python3 -m black --verbose .

In VS Code, use the Black extension for in-IDE formatting.

You can also use ruff as a formatter:

                python -m ruff format .

AI-Assisted Coding
with GitHub Copilot

A raccoon building a robot and reading

GitHub Copilot

GitHub Copilot works particularly well for writing web apps, since there are many common patterns across web apps.

Getting started with GitHub Copilot for students:

Get Copilot today! gh.io/sigcse2024

Many ways to invoke Copilot

  • Editor: Just type and it will suggest code Screenshot of Copilot completing Python code
  • Chat: Ask questions about your code or code topics. Screenshot of Copilot chat
  • Context menu: Ask it to explain, fix, or test selected code. Screenshot of Copilot inline chat

Prompting Copilot

  • Provide context
    • Open files
    • Comments
    • Imports
    • Names
    • Types
  • Be predictable
    • Naming conventions
    • Software architecture patterns

📖 Blog: Best practices for prompting GitHub Copilot in VS Code
🎥 Video: Best practices for prompting GitHub Copilot in VS Code

Avoiding Copilot confabulations

  • Paste in example code from docs
  • Be wary when asking about niche libraries

Find out ASAP if Copilot made something up:

  • Use real-time linters to check your work
  • Write tests for your code


A raccoon dressed like a ladybug

Testing pyramid

Software testing pyramid

Should you start at top or bottom? Start somewhere, atleast!

Unit testing in Python

Screenshot of pytest tests for summer library

Most commonly used libraries:

Code coverage matters

Code coverage is a measure of how much of your code is tested by your tests, either in terms of lines of code or branches of code.

Set a minimum threshold for code coverage, and use a tool like coverage to measure it.

Screenshot of coverage report
Source: GitHub actions

End-to-end testing

  • selenium: Can be used for a wide variety of browsers
  • playwright: More limited browser-wise, but faster/less flaky 😊

                def test_destinations(page: Page, live_server_url: str):
                    page.get_by_role("link", name="Destinations").click()
                    expect(page).to_have_title("ReleCloud - Destinations")

Integrating testing into projects

  • Local: Run tests with python -m pytest or python -m unittest
  • CI/CD: Run tests on every commit/push
  • Code coverage: Set a minimum threshold

For student projects, you could give them the tests and ask them to write the code to pass the tests, or you could give them the code and ask them to write the tests - or both!

Teaching materials for testing

Get workshop materials for "Testing Web Apps" from github.com/pamelafox/python-web-apps

👩🏼‍🏫 Attend our live stream covering the workshops in June.

Cloud deployment

A raccoon with a background of clouds and Azure logo

Why cloud deployment?

Screenshot of Azure student free credits

Cloud deployment is a good way to:

  • Make an app accessible to others
  • Get experience with cloud services
  • Learn about security, performance, and scaling

Azure is a good choice for students because of the free credits and the many services that are available.

🔗 aka.ms/azureforstudents

Azure hosting options

Azure Container Apps Azure Functions
Azure Kubernetes Service Container Management Azure App Service Serverless
Environment Containers PaaS
Cloud Azure

For students, App Service or Container Apps are good options.

Additional Azure services

Most web apps need more than just hosting:

Databases PostGreSQL, MySQL, CosmosDB, ...
Storage Blob Storage, Files, Archive Storage, ...
Networking DNS Zone, Virtual Network, VPN Gateway, ...
Caching CDN, Front Door, ...
Security Key Vault, Security Center, ...
Machine Learning + AI OpenAI, Translator, Bot Service, Computer Vision, ...
...and more!

Azure architecture for web apps

Diagram of Azure architecture for web apps with App Service, PostgreSQL, Key Vault
  • App Service plan: sets up scaling rules and environment for app
  • App Service webapp: actual app with endpoint
  • PostgreSQL: database for app
  • Key Vault: store secrets like database password

Ways to deploy to Azure

Screenshot of Azure Portal for Create Web App template
Source: Deploy a web app to Azure

UI based:

  • Azure Portal
  • VS Code Azure extension

Command based:

  • GitHub Actions
  • Azure CLI
                            az webapp up --name myapp --sku F1
  • Azure Developer CLI (+ infrastructure as code) 🥰
                            azd up

More example repos

All of these repos are set up for easy Azure deployment.

App Service Functions Container Apps
Django + PG Travel app
Quiz app
+ VNET: Reviews app
Travel app
Flask Simple App Simple API Simple App
Simple API
+ CDN: App
+ PostgreSQL Travel app
Quiz app
+ VNET: Reviews app
Travel app
Surveys App
FastAPI Salary API Simple API
+ APIM: Simple API
+ CDN: Maps API
Simple API
+ PostgreSQL Travel app Travel app
+ MongoDB Todo API Todo API Todo API

Microsoft resources for Edu

Get Copilot today! 🔗 gh.io/sigcse2024

Get Azure today! 🔗 aka.ms/azureforstudents

Sign up for Microsoft.Source

QR code for Microsoft.Source

Receive a regular digest of relevant technical content, events, and training.

Get the best of the newest resources, tools, and guidance to help developers quickly build and deploy on Azure.

Get links from today's session.

🔗 aka.ms/AApmimn

Thank you!

Photo of Pamela smiling with a stuffed elephant

Grab the slides @ aka.ms/teaching-python-web-sigcse

Find me online at:

Mastodon @pamelafox@fosstodon.org
Twitter @pamelafox
GitHub www.github.com/pamelafox
Website pamelafox.org

Any questions?

A bunch of raccoon students with computers