Skip to content

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.

Live session

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:

ModuleWhat it's for
datetimeDates and times
pathlibFile and folder paths that work on macOS and Windows
loggingWriting log messages about what your program is doing
reFinding and cleaning up patterns in text, such as phone numbers or order codes
enumValues that come from a fixed set of options (see below)
collectionsExtra kinds of lists and dictionaries for counting and grouping
from datetime import date

print(date.today())   # 2026-11-02
  • datetime is the module.
  • date is 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_PROGRES is 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.