Week 2 · Python for real work and SQL
Enums and the standard library
Use the modules that come with Python, the different ways to import them, and enums for values that come from a fixed set of options.
The standard library
A module is a file of Python code you can import into your own code to add new features. You already used one in week 1: import json.
You can install extra packages written by other people with uv add, but Python already comes with a large collection of modules called the standard library. A few you'll use often:
| Module | What it's for |
|---|---|
datetime | Dates and times |
pathlib | File and folder paths that work on macOS and Windows |
logging | Writing log messages about what your program is doing |
re | Finding and cleaning up patterns in text, such as phone numbers or order codes |
enum | Values that come from a fixed set of options (see below) |
collections | Extra kinds of lists and dictionaries for counting and grouping |
from datetime import date
print(date.today()) # 2026-11-02
datetimeis the module.dateis the thing you import from it.
How do you know a module is in the standard library? You can import it without installing anything with uv add first.
Ways to import
You'll see imports written in these forms:
import datetime # the whole module: use it as datetime.date.today()
from datetime import date # one thing from it: use it as date.today()
from pathlib import Path # same idea: use it as Path("week-02")
Put your imports at the top of the file. If you import something and never use it, Ruff removes it when you save.
Enums
An enum (short for enumeration) is a good fit when a value must be one of a small, fixed set of options: an order's status, a ticket's priority, a payment method.
The problem with plain strings
If you use plain strings everywhere, they're easy to mistype:
status = "inprogress"
Was that supposed to be "in_progress"? Python can't tell you. The code runs, and every check like if status == "in_progress" quietly comes out false.
Creating an enum
from enum import StrEnum
class TaskStatus(StrEnum):
PLANNED = "planned"
IN_PROGRESS = "in_progress"
BLOCKED = "blocked"
DONE = "done"
class TaskStatus(StrEnum): creates a new type called TaskStatus, built on StrEnum. You'll learn more about classes later. For now, read it as "these are all the allowed statuses". Each line inside is one option: a name on the left and its text value on the right. The names are written in capitals by convention, because they never change.
Use the options with a dot:
status = TaskStatus.IN_PROGRESS
print(status) # in_progress
print(status == "in_progress") # True
print(f"Status: {status}") # Status: in_progress
for option in TaskStatus:
print(option) # planned, in_progress, blocked, done (one per line)
A StrEnum behaves like the text it stands for, so it prints, compares and saves to JSON just like a string.
Rejecting bad values
Data from files, forms and APIs arrives as plain text. Turn it into your enum, and a bad value fails straight away with a clear message:
TaskStatus("done") # TaskStatus.DONE
TaskStatus("inprogress") # ValueError: 'inprogress' is not a valid TaskStatus
You can catch that ValueError with try and except, exactly as you did in week 1.
Why use enums instead of strings
- Autocomplete works. Type
TaskStatus.and VS Code lists every option. - Typos are easier to spot.
TaskStatus.IN_PROGRESis an error the moment it runs, and VS Code underlines it before you even run it. A misspelled string never is. - Bad values are easier to reject. One line checks a value against every allowed option.
Letting Python fill in the values
Typing each value twice gets repetitive. auto() fills it in for you: in a StrEnum, the value becomes the name in lowercase.
from enum import StrEnum, auto
class TaskPriority(StrEnum):
LOW = auto()
MEDIUM = auto()
HIGH = auto()
URGENT = auto()
print(TaskPriority.LOW) # low
print(repr(TaskPriority.LOW)) # <TaskPriority.LOW: 'low'>
print() shows the value. repr() shows the full enum, which is also what you see when you type TaskPriority.LOW straight into the python3 interpreter.
Other kinds of enum
Python also has the plain Enum, and IntEnum for options that stand for whole numbers. For most FDE work, where values come from and go back to JSON as text, StrEnum is the one to reach for.