Docs: second improvement pass (#603)

## Summary

- **Auth tutorial**: fix deprecated `datetime.utcnow()` →
`datetime.now(timezone.utc)`, add role-based access control section, add
auth strategy comparison guide
- **WebSocket tutorial**: use `WebSocketDisconnect` instead of bare
`Exception` in chat example, add connection lifecycle section with close
codes, add rejected connection test example
- **SQLAlchemy tutorial**: modernize from `Column()` to
`mapped_column()` / `Mapped[]` (SQLAlchemy 2.0 style with type checker
support)
- **Deployment**: use `uv` in Docker example instead of pip, fix stale
`uv.lock` reference in production checklist
- **Quickstart**: link to all tutorials in "next steps" (was only
linking to 3 of 9)
- **Sandbox**: rewrite with project layout tree, mypy command, and
pattern-matching test examples

## Test plan
- [x] `make html` builds cleanly
- [x] All 199 tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 16:00:56 -04:00
committed by GitHub
parent 536428a787
commit 1c729c8542
6 changed files with 172 additions and 36 deletions
+11 -10
View File
@@ -28,8 +28,8 @@ SQLAlchemy models map Python classes to database tables. Each attribute
becomes a column::
# models.py
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
@@ -37,15 +37,16 @@ becomes a column::
class Book(Base):
__tablename__ = "books"
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String, nullable=False)
author = Column(String, nullable=False)
year = Column(Integer, nullable=False)
isbn = Column(String, nullable=True)
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
title: Mapped[str] = mapped_column(String, nullable=False)
author: Mapped[str] = mapped_column(String, nullable=False)
year: Mapped[int] = mapped_column(nullable=False)
isbn: Mapped[str | None] = mapped_column(String, nullable=True)
``DeclarativeBase`` is SQLAlchemy's modern base class (SQLAlchemy 2.0+).
Each model class corresponds to a table, and each ``Column`` corresponds
to a column in that table.
This uses SQLAlchemy 2.0's ``Mapped`` type annotations and
``mapped_column()``, which give you type checker support and cleaner
syntax than the older ``Column()`` style. Each model class corresponds
to a table, and each ``mapped_column()`` corresponds to a column.
Database Setup