Skip to content

Commit 646a904

Browse files
authored
docs: additional usage cleanup (#240)
More doc cleanup
1 parent d302608 commit 646a904

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1177
-551
lines changed

AGENTS.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,23 @@ When processing user input that may be incomplete or malformed, use a two-tier a
507507

508508
**Implementation Pattern:**
509509

510+
## Recent edit: Configuration examples (2025-11-04)
511+
512+
- Updated docs/examples/usage examples: consolidated example filenames to
513+
docs/examples/usage/test_configuration_*.py and ensured the documentation
514+
references match the renamed examples.
515+
- Added an explicit :lines: range and a :dedent: directive to the
516+
literalinclude for test_configuration_23.py so Sphinx renders the snippet
517+
with correct indentation.
518+
- Built the Sphinx documentation (make docs) and verified HTML output was
519+
generated successfully. Two minor warnings were reported (dedent and a
520+
missing stylesheet copy) but they did not prevent the build.
521+
- Updated project TODOs to reflect completed steps.
522+
523+
This summary documents the small documentation and example maintenance
524+
performed on the configuration usage guide and can be expanded into a
525+
longer changelog entry if desired.
526+
510527
```python
511528
def parse_user_input(content: str, source: str) -> "dict[str, Result]":
512529
"""Parse user input with two-tier error handling.
@@ -2025,6 +2042,14 @@ class GoodDriverFeatures(TypedDict):
20252042

20262043
### Compliance Table
20272044

2045+
### Change log: configuration examples
2046+
2047+
- Renamed documentation example references to use docs/examples/usage/test_configuration_*.py
2048+
- Added explicit :lines: ranges and :dedent: directive for the literalinclude at the top of docs/usage/configuration.rst
2049+
- Rebuilt documentation to verify the changes (make docs). Build completed with 2 warnings about dedent and a missing stylesheet; output HTML written to docs/_build/html
2050+
2051+
### Compliance Table
2052+
20282053
Current state of all adapters (as of type-cleanup branch):
20292054

20302055
| Adapter | TypedDict | Auto-Detect | enable_ Prefix | Defaults | Grade | Notes |
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
from sqlspec import SQLSpec
2-
from sqlspec.adapters.sqlite import SqliteConfig
3-
41
__all__ = ("test_quickstart_1",)
52

63

74
def test_quickstart_1() -> None:
8-
# Create SQLSpec instance and configure database
5+
# start-example
6+
from sqlspec import SQLSpec
7+
from sqlspec.adapters.sqlite import SqliteConfig
8+
99
db_manager = SQLSpec()
1010
db = db_manager.add_config(SqliteConfig(pool_config={"database": ":memory:"}))
1111

12-
# Execute a query
1312
with db_manager.provide_session(db) as session:
1413
result = session.execute("SELECT 'Hello, SQLSpec!' as message")
15-
print(result.get_first()) # {'message': 'Hello, SQLSpec!'}
14+
print(result.get_first())
15+
# end-example
1616

1717
assert result.get_first() == {"message": "Hello, SQLSpec!"}
Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,42 @@
1-
from sqlspec import SQLSpec
2-
from sqlspec.adapters.sqlite import SqliteConfig
3-
41
__all__ = ("test_quickstart_2",)
52

63

74
def test_quickstart_2() -> None:
5+
# start-example
6+
from sqlspec import SQLSpec
7+
from sqlspec.adapters.sqlite import SqliteConfig
8+
89
db_manager = SQLSpec()
910
db = db_manager.add_config(SqliteConfig(pool_config={"database": ":memory:"}))
1011

1112
with db_manager.provide_session(db) as session:
12-
# Create a table
13-
_ = session.execute("""
13+
_ = session.execute(
14+
"""
1415
CREATE TABLE users (
1516
id INTEGER PRIMARY KEY,
1617
name TEXT NOT NULL,
1718
email TEXT UNIQUE NOT NULL
1819
)
19-
""")
20+
"""
21+
)
2022

21-
# Insert data
2223
_ = session.execute("INSERT INTO users (name, email) VALUES (?, ?)", "Alice", "alice@example.com")
2324

24-
# Insert multiple rows
2525
_ = session.execute_many(
2626
"INSERT INTO users (name, email) VALUES (?, ?)",
2727
[("Bob", "bob@example.com"), ("Charlie", "charlie@example.com")],
2828
)
2929

30-
# Query all users
3130
users = session.select("SELECT * FROM users")
3231
print(f"All users: {users}")
3332

34-
# Query single user
35-
alice = session.select_one("SELECT * FROM users WHERE name = ?", "Alice")
33+
alice = session.select_one_or_none("SELECT * FROM users WHERE name = ?", "Alice")
3634
print(f"Alice: {alice}")
3735

38-
# Query scalar value
3936
count = session.select_value("SELECT COUNT(*) FROM users")
4037
print(f"Total users: {count}")
38+
# end-example
4139

42-
assert len(users) == 3 # noqa: PLR2004
40+
assert len(users) == 3
4341
assert alice == {"id": 1, "name": "Alice", "email": "alice@example.com"}
44-
assert count == 3 # noqa: PLR2004
42+
assert count == 3

docs/examples/quickstart/quickstart_3.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,36 @@
1-
from pydantic import BaseModel
1+
__all__ = ("test_quickstart_3",)
22

3-
from sqlspec import SQLSpec
4-
from sqlspec.adapters.sqlite import SqliteConfig
5-
6-
__all__ = ("User",)
73

4+
def test_quickstart_3() -> None:
5+
# start-example
6+
from pydantic import BaseModel
87

9-
class User(BaseModel):
10-
id: int
11-
name: str
12-
email: str
8+
from sqlspec import SQLSpec
9+
from sqlspec.adapters.sqlite import SqliteConfig
1310

11+
class User(BaseModel):
12+
id: int
13+
name: str
14+
email: str
1415

15-
def test_quickstart_3() -> None:
1616
db_manager = SQLSpec()
1717
db = db_manager.add_config(SqliteConfig(pool_config={"database": ":memory:"}))
1818

1919
with db_manager.provide_session(db) as session:
20-
# Setup
21-
_ = session.execute("""
20+
_ = session.execute(
21+
"""
2222
CREATE TABLE users (id INTEGER, name TEXT, email TEXT)
23-
""")
23+
"""
24+
)
2425
_ = session.execute("INSERT INTO users VALUES (?, ?, ?)", 1, "Alice", "alice@example.com")
2526

26-
# Type-safe query - returns User instance
2727
user = session.select_one("SELECT * FROM users WHERE id = ?", 1, schema_type=User)
28+
print(f"User: {user.name} ({user.email})")
2829

29-
# Now you have type hints and autocomplete!
30-
print(f"User: {user.name} ({user.email})") # IDE knows these fields exist
31-
32-
# Multiple results
3330
all_users = session.select("SELECT * FROM users", schema_type=User)
34-
for u in all_users:
35-
print(f"User: {u.name}") # Each item is a typed User
31+
for typed_user in all_users:
32+
print(f"User: {typed_user.name}")
33+
# end-example
3634

3735
assert user == User(id=1, name="Alice", email="alice@example.com")
3836
assert len(all_users) == 1
Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
from pydantic import BaseModel
1+
"""Async quickstart example."""
22

3-
from sqlspec import SQLSpec
4-
from sqlspec.adapters.aiosqlite import AiosqliteConfig
3+
import pytest
54

6-
__all__ = ("User", "test_quickstart_4")
5+
__all__ = ("test_quickstart_4",)
76

87

9-
class User(BaseModel):
10-
id: int
11-
name: str
12-
email: str
8+
@pytest.mark.asyncio
9+
async def test_quickstart_4() -> None:
10+
"""Demonstrate async SQLSpec usage."""
11+
# start-example
12+
from pydantic import BaseModel
1313

14+
from sqlspec import SQLSpec
15+
from sqlspec.adapters.aiosqlite import AiosqliteConfig
16+
17+
class User(BaseModel):
18+
id: int
19+
name: str
20+
email: str
1421

15-
async def test_quickstart_4() -> None:
1622
db_manager = SQLSpec()
1723
db = db_manager.add_config(AiosqliteConfig(pool_config={"database": ":memory:"}))
1824

1925
async with db_manager.provide_session(db) as session:
20-
# Create table
21-
_ = await session.execute("""
26+
await session.execute(
27+
"""
2228
CREATE TABLE users (id INTEGER, name TEXT, email TEXT)
23-
""")
24-
25-
# Insert data
26-
_ = await session.execute("INSERT INTO users VALUES (?, ?, ?)", 1, "Alice", "alice@example.com")
27-
28-
# Type-safe async query
29+
"""
30+
)
31+
await session.execute("INSERT INTO users VALUES (?, ?, ?)", 1, "Alice", "alice@example.com")
2932
user = await session.select_one("SELECT * FROM users WHERE id = ?", 1, schema_type=User)
30-
3133
print(f"User: {user.name}")
34+
# end-example
3235

3336
assert user == User(id=1, name="Alice", email="alice@example.com")
34-
assert isinstance(user, User)
35-
assert user.name == "Alice"
36-
assert user.email == "alice@example.com"
Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,58 @@
1-
import os
2-
from typing import Any
1+
"""Async PostgreSQL quickstart example."""
32

4-
from pydantic import BaseModel
3+
import pytest
54

6-
from sqlspec import SQLSpec
7-
from sqlspec.adapters.asyncpg import AsyncpgConfig
5+
__all__ = ("test_quickstart_5",)
86

9-
__all__ = ("User", "test_quickstart_5")
107

11-
12-
class User(BaseModel):
13-
id: int
14-
name: str
15-
email: str
16-
17-
18-
def _pool_config() -> "dict[str, Any]":
19-
return {
20-
"host": os.getenv("SQLSPEC_QUICKSTART_PG_HOST", "localhost"),
21-
"port": int(os.getenv("SQLSPEC_QUICKSTART_PG_PORT", "5432")),
22-
"user": os.getenv("SQLSPEC_QUICKSTART_PG_USER", "postgres"),
23-
"password": os.getenv("SQLSPEC_QUICKSTART_PG_PASSWORD", "postgres"),
24-
"database": os.getenv("SQLSPEC_QUICKSTART_PG_DATABASE", "mydb"),
25-
}
26-
27-
28-
async def _seed_users(session: Any) -> None:
29-
await session.execute(
30-
"""
31-
CREATE TABLE IF NOT EXISTS users (
32-
id INTEGER PRIMARY KEY,
33-
name TEXT NOT NULL,
34-
email TEXT NOT NULL
8+
@pytest.mark.asyncio
9+
async def test_quickstart_5() -> None:
10+
"""Demonstrate async PostgreSQL usage with SQLSpec."""
11+
# start-example
12+
import os
13+
from typing import Any
14+
15+
from pydantic import BaseModel
16+
17+
from sqlspec import SQLSpec
18+
from sqlspec.adapters.asyncpg import AsyncpgConfig
19+
20+
class User(BaseModel):
21+
id: int
22+
name: str
23+
email: str
24+
25+
def pool_config() -> "dict[str, Any]":
26+
return {
27+
"host": os.getenv("SQLSPEC_QUICKSTART_PG_HOST", "localhost"),
28+
"port": int(os.getenv("SQLSPEC_QUICKSTART_PG_PORT", "5432")),
29+
"user": os.getenv("SQLSPEC_QUICKSTART_PG_USER", "postgres"),
30+
"password": os.getenv("SQLSPEC_QUICKSTART_PG_PASSWORD", "postgres"),
31+
"database": os.getenv("SQLSPEC_QUICKSTART_PG_DATABASE", "mydb"),
32+
}
33+
34+
async def seed_users(session: Any) -> None:
35+
await session.execute(
36+
"""
37+
CREATE TABLE IF NOT EXISTS users (
38+
id INTEGER PRIMARY KEY,
39+
name TEXT NOT NULL,
40+
email TEXT NOT NULL
41+
)
42+
"""
43+
)
44+
await session.execute("TRUNCATE TABLE users")
45+
await session.execute(
46+
"INSERT INTO users (id, name, email) VALUES ($1, $2, $3)", 1, "Alice", "alice@example.com"
3547
)
36-
"""
37-
)
38-
await session.execute("TRUNCATE TABLE users")
39-
await session.execute("INSERT INTO users (id, name, email) VALUES ($1, $2, $3)", 1, "Alice", "alice@example.com")
40-
4148

42-
async def test_quickstart_5() -> None:
4349
db_manager = SQLSpec()
44-
db = db_manager.add_config(AsyncpgConfig(pool_config=_pool_config()))
50+
db = db_manager.add_config(AsyncpgConfig(pool_config=pool_config()))
4551

4652
async with db_manager.provide_session(db) as session:
47-
await _seed_users(session)
48-
49-
# PostgreSQL uses $1, $2 for parameters instead of ?
53+
await seed_users(session)
5054
user = await session.select_one("SELECT * FROM users WHERE id = $1", 1, schema_type=User)
5155
print(f"User: {user.name}")
56+
# end-example
5257

5358
assert user == User(id=1, name="Alice", email="alice@example.com")
Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
from sqlspec import SQLSpec
2-
from sqlspec.adapters.duckdb import DuckDBConfig
3-
from sqlspec.adapters.sqlite import SqliteConfig
4-
51
__all__ = ("test_quickstart_6",)
62

73

84
def test_quickstart_6() -> None:
9-
db_manager = SQLSpec()
5+
# start-example
6+
from sqlspec import SQLSpec
7+
from sqlspec.adapters.duckdb import DuckDBConfig
8+
from sqlspec.adapters.sqlite import SqliteConfig
109

11-
# Register multiple databases
10+
db_manager = SQLSpec()
1211
sqlite_db = db_manager.add_config(SqliteConfig(pool_config={"database": "app.db"}))
1312
duckdb_db = db_manager.add_config(DuckDBConfig(pool_config={"database": "analytics.duckdb"}))
1413

15-
# Use different databases
1614
with db_manager.provide_session(sqlite_db) as sqlite_session:
1715
users = sqlite_session.select("SELECT 1")
1816

1917
with db_manager.provide_session(duckdb_db) as duckdb_session:
2018
analytics = duckdb_session.select("SELECT 1")
19+
# end-example
2120

2221
assert isinstance(users, list)
2322
assert isinstance(analytics, list)

0 commit comments

Comments
 (0)