Files
awesome-copilot/skills/create-web-form/references/python-flask-app.md
jhauga 27149859a4 Add skill to create web forms
Add skill to create web forms
2026-02-09 19:22:54 -05:00

9.7 KiB

Python Flask App Reference

Source: https://realpython.com/python-web-applications/

This reference covers building Python web applications, including how the web works, choosing a framework, building and deploying a Flask application, and understanding key web development concepts.


Overview

Python offers several approaches to web development:

  • Web frameworks (Flask, Django, FastAPI) that handle routing, templates, and data
  • Hosting platforms (Google App Engine, PythonAnywhere, Heroku, etc.) for deployment
  • WSGI (Web Server Gateway Interface) as the standard interface between web servers and Python applications

How the Web Works

The HTTP Request-Response Cycle

  1. A client (browser) sends an HTTP request to a server
  2. The server processes the request and returns an HTTP response
  3. The browser renders the response content

HTTP Methods

Method Purpose
GET Retrieve data from the server
POST Submit data to the server
PUT Update existing data on the server
DELETE Remove data from the server

URL Structure

https://example.com:443/path/to/resource?key=value#section
  |         |        |        |              |        |
scheme     host     port     path          query   fragment

Choosing a Python Web Framework

Flask

  • Micro-framework -- minimal core with extensions for added functionality
  • Best for small to medium applications, APIs, and learning
  • No database abstraction layer, form validation, or other components built in
  • Extensions available for everything (SQLAlchemy, WTForms, Login, etc.)

Django

  • Full-stack framework -- batteries included
  • Best for large applications with built-in ORM, admin panel, authentication
  • Opinionated project structure

FastAPI

  • Modern, fast, async framework -- built on Starlette and Pydantic
  • Best for building APIs with automatic documentation
  • Built-in data validation and serialization

Building a Flask Application

Installation

python -m pip install flask

Minimal Application

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

Running the Application

# Method 1: Direct execution
python app.py

# Method 2: Using Flask CLI
export FLASK_APP=app.py
export FLASK_ENV=development
flask run

Routing

Basic Routes

@app.route('/')
def home():
    return 'Home Page'

@app.route('/about')
def about():
    return 'About Page'

@app.route('/contact')
def contact():
    return 'Contact Page'

Dynamic Routes with URL Parameters

@app.route('/user/<username>')
def show_user(username):
    return f'User: {username}'

@app.route('/post/<int:post_id>')
def show_post(post_id):
    return f'Post ID: {post_id}'

URL Converters

Converter Description
string Accepts any text without a slash (default)
int Accepts positive integers
float Accepts positive floating-point values
path Like string but also accepts slashes
uuid Accepts UUID strings

Specifying HTTP Methods

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_login()
    return show_login_form()

Templates with Jinja2

Basic Template Rendering

from flask import render_template

@app.route('/hello/<name>')
def hello(name):
    return render_template('hello.html', name=name)

Template Inheritance

Base template (templates/base.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}My App{% endblock %}</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <nav>
        <a href="{{ url_for('home') }}">Home</a>
        <a href="{{ url_for('about') }}">About</a>
    </nav>

    <main>
        {% block content %}{% endblock %}
    </main>

    <footer>
        <p>My Web App</p>
    </footer>
</body>
</html>

Child template (templates/home.html):

{% extends "base.html" %}

{% block title %}Home{% endblock %}

{% block content %}
    <h1>Welcome to My App</h1>
    <p>This is the home page.</p>
{% endblock %}

Jinja2 Template Syntax

Syntax Purpose
{{ variable }} Output the value of a variable
{% statement %} Execute a control flow statement
{# comment #} Template comment (not rendered)
{{ url_for('func') }} Generate a URL for a view function
{{ url_for('static', filename='style.css') }} Generate a URL for a static file

Control Flow in Templates

{% if user %}
    <h1>Hello, {{ user.name }}!</h1>
{% else %}
    <h1>Hello, stranger!</h1>
{% endif %}

<ul>
{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

Project Structure

my_flask_app/
    app.py                  # Application entry point
    config.py               # Configuration settings
    requirements.txt        # Python dependencies
    static/                 # Static files (CSS, JS, images)
        style.css
        script.js
    templates/              # Jinja2 HTML templates
        base.html
        home.html
        about.html
    models.py               # Database models (if using a database)
    forms.py                # WTForms form classes

Larger Application Structure (Blueprints)

my_flask_app/
    app/
        __init__.py         # Application factory
        models.py
        auth/
            __init__.py
            routes.py
            forms.py
            templates/
                login.html
                register.html
        main/
            __init__.py
            routes.py
            templates/
                home.html
                about.html
    config.py
    requirements.txt
    run.py

Working with Static Files

Flask automatically serves files from the static/ directory.

Referencing Static Files in Templates

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<script src="{{ url_for('static', filename='script.js') }}"></script>
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">

Database Integration

Using Flask-SQLAlchemy

pip install Flask-SQLAlchemy
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'

Creating the Database

with app.app_context():
    db.create_all()

Deployment

Deploying to PythonAnywhere

  1. Create a free account at pythonanywhere.com
  2. Upload your code via git or the file browser
  3. Set up a virtual environment and install dependencies
  4. Configure a WSGI file pointing to your Flask app
  5. Reload the web application

Deploying to Heroku

  1. Create a Procfile:
web: gunicorn app:app
  1. Create a requirements.txt:
pip freeze > requirements.txt
  1. Deploy:
heroku create
git push heroku main

Deploying to Google App Engine

Create an app.yaml configuration:

runtime: python39
entrypoint: gunicorn -b :$PORT app:app

handlers:
  - url: /static
    static_dir: static
  - url: /.*
    script: auto

WSGI Servers

For production, use a WSGI server instead of Flask's built-in development server:

Server Description
Gunicorn Production-grade WSGI server for Unix
Waitress Production-grade WSGI server for Windows and Unix
uWSGI Full-featured WSGI server with many deployment options
# Using Gunicorn
pip install gunicorn
gunicorn app:app

# Using Waitress
pip install waitress
waitress-serve --port=5000 app:app

Environment Configuration

Using Environment Variables

import os

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-fallback-key')
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///site.db')
    DEBUG = os.environ.get('FLASK_DEBUG', False)

Using python-dotenv

pip install python-dotenv

Create a .env file:

SECRET_KEY=your-secret-key-here
DATABASE_URL=sqlite:///site.db
FLASK_DEBUG=1

Load in your application:

from dotenv import load_dotenv
load_dotenv()

Key Takeaways

  1. Flask is a micro-framework -- it provides routing, templates, and request handling while leaving other choices (database, forms, authentication) to extensions.
  2. Use Jinja2 template inheritance to keep HTML DRY with base templates and child blocks.
  3. Organize your project with a clear structure: separate templates/, static/, and Python modules.
  4. Use Blueprints for larger applications to group related routes and templates.
  5. Never use the Flask development server in production -- use Gunicorn, Waitress, or uWSGI.
  6. Store configuration in environment variables using python-dotenv or platform-specific config.
  7. Use url_for() to generate URLs dynamically rather than hard-coding paths.
  8. Flask-SQLAlchemy provides a convenient ORM layer for database operations.
  9. Multiple hosting platforms support Flask apps: PythonAnywhere, Heroku, Google App Engine, and others.