Python course Β· Module 5: Flask and Web Apps

Frontend basics for Python devs

9 min read
In this lesson7

Welcome to Module 5! Darwin here with a new chapter - Web Development!

So far you've been working exclusively with the backend - Python, databases, API. Now it's time to learn the frontend - the user interface that visitors see on your website!

Safari Analogy: The backend is like the research laboratory behind the scenes - Python, databases, logic. The frontend is the tourist information center - colorful boards, interactive maps, "See more about lions" buttons!

Why does a Python dev need frontend?

As a Python developer you'll be building web applications - so you need frontend basics!

Frontend = HTML + CSS + JavaScript

  • HTML - structure (what's on the page)
  • CSS - appearance (how it looks)
  • JavaScript - interaction (what happens on click)

Analogy: HTML is the dinosaur skeleton, CSS is the skin and colors, JavaScript is the muscles that allow movement!

HTML - page structure

HTML (HyperText Markup Language) is a markup language defining the structure of a page.

Basic structure

1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Safari Database</title>
7</head>
8<body>
9    <h1>Welcome to Safari Database</h1>
10    <p>Species data management system</p>
11</body>
12</html>

Structure:

  • <!DOCTYPE html> - document type declaration
  • <html> - root element
  • <head> - metadata (title, charset, styles)
  • <body> - visible content on the page

Important HTML tags

1<!-- Headings (h1 most important, h6 least) -->
2<h1>Safari Database</h1>
3<h2>African Species</h2>
4<h3>Lion (Panthera leo)</h3>
5
6<!-- Paragraph -->
7<p>The lion is Africa's largest predator...</p>
8
9<!-- Link -->
10<a href="/species/lion">See lion details</a>
11
12<!-- Image -->
13<img src="/static/images/lion.jpg" alt="Lion in Serengeti">
14
15<!-- Unordered list -->
16<ul>
17    <li>Lion</li>
18    <li>Elephant</li>
19    <li>Cheetah</li>
20</ul>
21
22<!-- Ordered list -->
23<ol>
24    <li>Fetch data</li>
25    <li>Process</li>
26    <li>Display</li>
27</ol>
28
29<!-- Button -->
30<button>Add observation</button>
31
32<!-- Form -->
33<form action="/add-species" method="POST">
34    <label for="name">Name:</label>
35    <input type="text" id="name" name="name" required>
36
37    <label for="population">Population:</label>
38    <input type="number" id="population" name="population">
39
40    <button type="submit">Save</button>
41</form>
42
43<!-- Table -->
44<table>
45    <thead>
46        <tr>
47            <th>Species</th>
48            <th>Population</th>
49            <th>Habitat</th>
50        </tr>
51    </thead>
52    <tbody>
53        <tr>
54            <td>Lion</td>
55            <td>120</td>
56            <td>Savanna</td>
57        </tr>
58        <tr>
59            <td>Elephant</td>
60            <td>450</td>
61            <td>Savanna</td>
62        </tr>
63    </tbody>
64</table>
65
66<!-- Div - block container -->
67<div class="species-card">
68    <h3>Lion</h3>
69    <p>Population: 120</p>
70</div>
71
72<!-- Span - inline container -->
73<p>Status: <span class="endangered">Endangered</span></p>

HTML attributes

1<!-- class - CSS class -->
2<div class="species-card endangered">...</div>
3
4<!-- id - unique identifier -->
5<div id="lion-details">...</div>
6
7<!-- data-* - custom data attributes -->
8<div class="species" data-id="123" data-population="120">...</div>
9
10<!-- href - link -->
11<a href="https://example.com">Link</a>
12
13<!-- src, alt - images -->
14<img src="image.jpg" alt="Image description">
15
16<!-- placeholder, required - forms -->
17<input type="text" placeholder="Enter name" required>

CSS - styling the page

CSS (Cascading Style Sheets) defines the appearance of HTML elements.

Ways to add CSS

1<!-- 1. Inline CSS (not recommended) -->
2<p style="color: green; font-size: 18px;">Text</p>
3
4<!-- 2. Internal CSS (in <head>) -->
5<head>
6    <style>
7        p {
8            color: green;
9            font-size: 18px;
10        }
11    </style>
12</head>
13
14<!-- 3. External CSS (recommended) -->
15<head>
16    <link rel="stylesheet" href="/static/css/style.css">
17</head>

CSS selectors

1/* Tag selector */
2p {
3    color: #333;
4    line-height: 1.6;
5}
6
7/* Class selector */
8.species-card {
9    border: 2px solid #ddd;
10    padding: 20px;
11    margin: 10px;
12    border-radius: 8px;
13}
14
15/* ID selector */
16#lion-details {
17    background-color: #f9f9f9;
18}
19
20/* Attribute selector */
21[data-endangered="true"] {
22    border-color: red;
23}
24
25/* Child selector */
26.species-card > h3 {
27    color: #2c5f2d;
28}
29
30/* Hover state */
31button:hover {
32    background-color: #45a049;
33    cursor: pointer;
34}

Basic CSS properties

1/* Colors */
2.endangered {
3    color: red;
4    background-color: #ffe6e6;
5}
6
7/* Typography */
8h1 {
9    font-family: 'Arial', sans-serif;
10    font-size: 32px;
11    font-weight: bold;
12    text-align: center;
13}
14
15/* Box model */
16.species-card {
17    width: 300px;
18    height: 200px;
19    padding: 20px;      /* Inner spacing */
20    margin: 10px;       /* Outer spacing */
21    border: 2px solid #ddd;
22}
23
24/* Flexbox - layout */
25.species-list {
26    display: flex;
27    flex-wrap: wrap;
28    gap: 20px;
29    justify-content: center;
30}
31
32/* Grid - layout */
33.species-grid {
34    display: grid;
35    grid-template-columns: repeat(3, 1fr);
36    gap: 20px;
37}

Safari example - styling a species card

1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <title>Safari Database</title>
6    <style>
7        body {
8            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9            background-color: #f4f1de;
10            margin: 0;
11            padding: 20px;
12        }
13
14        h1 {
15            text-align: center;
16            color: #2c5f2d;
17        }
18
19        .species-list {
20            display: flex;
21            flex-wrap: wrap;
22            gap: 20px;
23            justify-content: center;
24            max-width: 1200px;
25            margin: 0 auto;
26        }
27
28        .species-card {
29            background-color: white;
30            border: 2px solid #e0afa0;
31            border-radius: 12px;
32            padding: 20px;
33            width: 280px;
34            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
35            transition: transform 0.2s;
36        }
37
38        .species-card:hover {
39            transform: translateY(-5px);
40            box-shadow: 0 6px 12px rgba(0,0,0,0.15);
41        }
42
43        .species-card.endangered {
44            border-color: #d62828;
45            border-width: 3px;
46        }
47
48        .species-name {
49            color: #2c5f2d;
50            font-size: 24px;
51            margin-top: 0;
52        }
53
54        .badge {
55            display: inline-block;
56            padding: 4px 8px;
57            border-radius: 4px;
58            font-size: 12px;
59            font-weight: bold;
60        }
61
62        .badge-endangered {
63            background-color: #d62828;
64            color: white;
65        }
66
67        .badge-safe {
68            background-color: #4caf50;
69            color: white;
70        }
71    </style>
72</head>
73<body>
74    <h1>Safari Database</h1>
75
76    <div class="species-list">
77        <div class="species-card endangered">
78            <h3 class="species-name">Lion</h3>
79            <p><strong>Population:</strong> 120 individuals</p>
80            <p><strong>Habitat:</strong> Savanna</p>
81            <span class="badge badge-endangered">Endangered</span>
82        </div>
83
84        <div class="species-card endangered">
85            <h3 class="species-name">African Elephant</h3>
86            <p><strong>Population:</strong> 450 individuals</p>
87            <p><strong>Habitat:</strong> Savanna</p>
88            <span class="badge badge-endangered">Endangered</span>
89        </div>
90
91        <div class="species-card">
92            <h3 class="species-name">Giraffe</h3>
93            <p><strong>Population:</strong> 850 individuals</p>
94            <p><strong>Habitat:</strong> Savanna</p>
95            <span class="badge badge-safe">Safe</span>
96        </div>
97    </div>
98</body>
99</html>

JavaScript - interactivity

JavaScript adds interaction - reactions to clicks, animations, dynamic changes.

JavaScript basics

1<!DOCTYPE html>
2<html>
3<head>
4    <title>Safari JS</title>
5</head>
6<body>
7    <h1 id="title">Safari Database</h1>
8    <button onclick="changeName()">Change title</button>
9    <button id="addBtn">Add species</button>
10
11    <div id="species-count">Species: 0</div>
12
13    <script>
14        // Variables
15        let speciesCount = 3;
16        const databaseName = "Safari DB";
17
18        // Function
19        function changeName() {
20            document.getElementById("title").textContent = "New title!";
21        }
22
23        // Event listener (better way than onclick)
24        document.getElementById("addBtn").addEventListener("click", function() {
25            speciesCount++;
26            document.getElementById("species-count").textContent = `Species: ${speciesCount}`;
27        });
28
29        // Console log
30        console.log("Page loaded!");
31
32        // Fetch data from API
33        fetch("/api/species")
34            .then(response => response.json())
35            .then(data => {
36                console.log("Data fetched:", data);
37            })
38            .catch(error => console.error("Error:", error));
39    </script>
40</body>
41</html>

DOM manipulation

1// Get element
2const title = document.getElementById("title");
3const cards = document.querySelectorAll(".species-card");
4const firstCard = document.querySelector(".species-card");
5
6// Change content
7title.textContent = "New title";
8title.innerHTML = "<strong>Bold title</strong>";
9
10// Change styles
11title.style.color = "red";
12title.style.fontSize = "32px";
13
14// Add/remove classes
15title.classList.add("highlight");
16title.classList.remove("old-class");
17title.classList.toggle("active");
18
19// Create new element
20const newCard = document.createElement("div");
21newCard.className = "species-card";
22newCard.innerHTML = `
23    <h3>Cheetah</h3>
24    <p>Population: 7100</p>
25`;
26
27// Add to page
28document.querySelector(".species-list").appendChild(newCard);
29
30// Remove element
31const cardToRemove = document.querySelector(".species-card");
32cardToRemove.remove();

Safari example - interactive list

1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <title>Interactive Safari</title>
6    <style>
7        body {
8            font-family: Arial, sans-serif;
9            max-width: 800px;
10            margin: 0 auto;
11            padding: 20px;
12            background-color: #f4f1de;
13        }
14
15        .add-form {
16            background: white;
17            padding: 20px;
18            border-radius: 8px;
19            margin-bottom: 20px;
20        }
21
22        input, button {
23            padding: 10px;
24            margin: 5px;
25            border-radius: 4px;
26            border: 1px solid #ddd;
27        }
28
29        button {
30            background-color: #2c5f2d;
31            color: white;
32            cursor: pointer;
33            border: none;
34        }
35
36        button:hover {
37            background-color: #45a049;
38        }
39
40        .species-card {
41            background: white;
42            padding: 15px;
43            margin: 10px 0;
44            border-radius: 8px;
45            border-left: 4px solid #2c5f2d;
46            display: flex;
47            justify-content: space-between;
48            align-items: center;
49        }
50
51        .delete-btn {
52            background-color: #d62828;
53            padding: 8px 12px;
54            font-size: 14px;
55        }
56
57        .delete-btn:hover {
58            background-color: #9d0208;
59        }
60    </style>
61</head>
62<body>
63    <h1>Safari Database - Interactive List</h1>
64
65    <div class="add-form">
66        <h3>Add new species</h3>
67        <input type="text" id="speciesName" placeholder="Species name">
68        <input type="number" id="speciesPopulation" placeholder="Population">
69        <button id="addBtn">Add</button>
70    </div>
71
72    <div id="speciesList"></div>
73
74    <p><strong>Total species:</strong> <span id="totalCount">0</span></p>
75
76    <script>
77        // Application state
78        let species = [
79            { id: 1, name: "Lion", population: 120 },
80            { id: 2, name: "Elephant", population: 450 },
81            { id: 3, name: "Cheetah", population: 7100 }
82        ];
83        let nextId = 4;
84
85        // Render list
86        function renderSpecies() {
87            const listElement = document.getElementById("speciesList");
88            listElement.innerHTML = "";
89
90            species.forEach(spec => {
91                const card = document.createElement("div");
92                card.className = "species-card";
93                card.innerHTML = `
94                    <div>
95                        <strong>${spec.name}</strong> - Population: ${spec.population} individuals
96                    </div>
97                    <button class="delete-btn" onclick="deleteSpecies(${spec.id})">Delete</button>
98                `;
99                listElement.appendChild(card);
100            });
101
102            // Update counter
103            document.getElementById("totalCount").textContent = species.length;
104        }
105
106        // Add species
107        document.getElementById("addBtn").addEventListener("click", function() {
108            const nameInput = document.getElementById("speciesName");
109            const popInput = document.getElementById("speciesPopulation");
110
111            const name = nameInput.value.trim();
112            const population = parseInt(popInput.value);
113
114            if (name && population) {
115                species.push({
116                    id: nextId++,
117                    name: name,
118                    population: population
119                });
120
121                // Clear form
122                nameInput.value = "";
123                popInput.value = "";
124
125                // Re-render
126                renderSpecies();
127            } else {
128                alert("Please fill in all fields!");
129            }
130        });
131
132        // Delete species
133        function deleteSpecies(id) {
134            if (confirm("Are you sure you want to delete this species?")) {
135                species = species.filter(s => s.id !== id);
136                renderSpecies();
137            }
138        }
139
140        // Initial render
141        renderSpecies();
142    </script>
143</body>
144</html>

How does it all work together?

HTML β†’ Structure ("what") CSS β†’ Appearance ("how it looks") JavaScript β†’ Interaction ("what happens")

1<!-- HTML - structure -->
2<button id="likeBtn" class="btn">Like it!</button>
3
4<!-- CSS - appearance -->
5<style>
6    .btn {
7        background-color: #4CAF50;
8        color: white;
9        padding: 15px 32px;
10        border: none;
11        border-radius: 4px;
12        cursor: pointer;
13    }
14    .btn.liked {
15        background-color: #f44336;
16    }
17</style>
18
19<!-- JavaScript - interaction -->
20<script>
21    document.getElementById("likeBtn").addEventListener("click", function() {
22        this.classList.toggle("liked");
23        this.textContent = this.classList.contains("liked")
24            ? "Don't like :("
25            : "Like it!";
26    });
27</script>

Python devs - what do you need to know?

Minimum frontend for Flask:

  1. HTML - basics (tags, forms, tables)
  2. CSS - basics (selectors, box model, flexbox)
  3. JavaScript - basics (DOM, event listeners, fetch)

You don't have to be a frontend expert - Flask with Jinja2 generates HTML for you!

What you'll do in Flask:

  • Creating templates (HTML with Jinja2)
  • Basic CSS for styling
  • Minimal JS for forms/validation

CSS Frameworks (ready-made styles) will help you quickly create nice interfaces:

  • Bootstrap - most popular
  • Tailwind CSS - utility-first
  • Bulma - simple and lightweight

Summary

In this lesson you learned:

  • Why a Python dev needs frontend
  • HTML - structure (tags, attributes, forms)
  • CSS - styling (selectors, colors, layout)
  • JavaScript - interaction (DOM, event listeners)
  • How HTML, CSS and JS work together
  • Practical Safari examples

Final Safari Analogy: The frontend is the park's information center - colorful boards (CSS), trail maps (HTML), interactive "See more" buttons (JavaScript). The backend is the laboratory behind the scenes (Python + databases)!

In the next lesson Darwin will show you Flask - a microframework for building web applications in Python!

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. What does HTML (HyperText Markup Language) define?

  2. 2. Which technologies make up the classic web frontend?

These are 2 of 3 questions for this lesson. Solve the rest in the game.

Hands-on tasks in the game

  • Click in order

    Arrange the basic HTML document structure in order from the beginning:

  • Horizontal ordering

    What does a correct first-level heading look like in HTML?

  • Horizontal ordering

    What does a correct link (anchor) look like in HTML?

  • Code editor

    Write a basic HTML page with an h1 heading 'Safari Database' and a paragraph with a description.

Useful articles