Skip to content

Commit adf4f3c

Browse files
authored
Merge pull request #226 from grillazz/switch-logger-to-rotoger
bump project deps
2 parents e8f9a30 + 27a895e commit adf4f3c

File tree

9 files changed

+137
-643
lines changed

9 files changed

+137
-643
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ safety: ## Check for insecure dependencies
6060

6161
.PHONY: py-upgrade
6262
py-upgrade: ## Upgrade Python syntax to a newer version
63-
pyupgrade --py313-plus `find app -name "*.py"`
63+
pyupgrade --py314-plus `find app -name "*.py"`
6464

6565
.PHONY: lint
6666
lint: ## Lint and format project code

README.md

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,10 @@ This example demonstrates the seamless integration of [FastAPI](https://fastapi.
4848
with [Pydantic 2.0](https://github.com/pydantic/pydantic), a robust and powerful data validation library.
4949
The integration is further enhanced by the use of [SQLAlchemy ORM](https://www.sqlalchemy.org/), a popular and feature-rich Object-Relational Mapping tool,
5050
and [PostgreSQL17](https://www.postgresql.org/docs/17/release.html) relational database.
51-
5251
The entire stack is connected using the [asyncpg](https://github.com/MagicStack/asyncpg) Database Client Library,
5352
which provides a robust and efficient way to interact with PostgreSQL databases in Python,
5453
leveraging the power of asyncio and event loops.
5554

56-
Notably, this example showcases the latest and greatest versions of SQLAlchemy and psycopg,
57-
which are renowned for their robustness, power, and speed. The inclusion of FastAPI adds a modern, fast, and high-performance web framework to the mix
58-
allowing for the rapid development of APIs with Python 3.13.
59-
60-
FastAPI has received significant recognition in the industry, including a review on thoughtworks Technology Radar in April 2021,
61-
where it was classified as a Trial technology, with comments praising its performance, ease of use,
62-
and features such as API documentation using OpenAPI. Additionally, FastAPI was recognized in the Python Developers Survey 2023 Results,
63-
conducted by the Python Software Foundation and JetBrains, where it was reported that 1 in 4 Python developers use FastAPI,
64-
with a 4 percentage point increase from the previous year.
65-
66-
6755
### Built With
6856
[![FastAPI][fastapi.tiangolo.com]][fastapi-url]
6957
[![Pydantic][pydantic.com]][pydantic-url]
@@ -106,7 +94,7 @@ Next models were generated with https://github.com/agronholm/sqlacodegen
10694

10795
To elevate the logging capabilities beyond simple colored output,
10896
this project has transitioned to [Rotoger](https://github.com/tinyplugins/rotoger).
109-
This powerful library provides a comprehensive, production-ready logging setup for modern asynchronous applications,
97+
This tiny library provides a comprehensive, production-ready logging setup for modern asynchronous applications,
11098
addressing challenges like log management, performance, and readability.
11199

112100
Rotoger is built upon the excellent [structlog](http://structlog.org/) library and brings several key advantages:
@@ -218,7 +206,7 @@ I've included a few of my favorites to kick things off!
218206

219207
## Change Log
220208
<details>
221-
<summary>2025 (3 changes)</summary>
209+
<summary>2025 (7 changes)</summary>
222210
<ul>
223211
<li>[SEP 2 2025] add sample high availability with nginx as load balancer</li>
224212
<li>[AUG 23 2025] intro exception handlers</li>

app/api/health.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
router = APIRouter()
1313

1414

15-
16-
1715
@router.get("/redis", status_code=status.HTTP_200_OK)
1816
async def redis_check(request: Request):
1917
"""

app/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ async def lifespan(app: FastAPI):
4747
def create_app() -> FastAPI:
4848
app = FastAPI(
4949
title="Stuff And Nonsense API",
50-
version="0.20.0",
50+
version="1.22.0",
5151
lifespan=lifespan,
5252
)
5353
app.include_router(stuff_router)

app/models/shakespeare.py

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ class Character(Base):
4646
abbrev: Mapped[str | None] = mapped_column(String(32))
4747
description: Mapped[str | None] = mapped_column(String(2056))
4848

49-
work: Mapped[list["Work"]] = relationship(
49+
work: Mapped[list[Work]] = relationship(
5050
"Work", secondary="shakespeare.character_work", back_populates="character"
5151
)
52-
paragraph: Mapped[list["Paragraph"]] = relationship(
52+
paragraph: Mapped[list[Paragraph]] = relationship(
5353
"Paragraph", back_populates="character"
5454
)
5555

@@ -122,11 +122,11 @@ class Work(Base):
122122
total_paragraphs: Mapped[int] = mapped_column(Integer)
123123
notes: Mapped[str | None] = mapped_column(Text)
124124

125-
character: Mapped[list["Character"]] = relationship(
125+
character: Mapped[list[Character]] = relationship(
126126
"Character", secondary="shakespeare.character_work", back_populates="work"
127127
)
128-
chapter: Mapped[list["Chapter"]] = relationship("Chapter", back_populates="work")
129-
paragraph: Mapped[list["Paragraph"]] = relationship(
128+
chapter: Mapped[list[Chapter]] = relationship("Chapter", back_populates="work")
129+
paragraph: Mapped[list[Paragraph]] = relationship(
130130
"Paragraph", back_populates="work"
131131
)
132132

@@ -170,8 +170,8 @@ class Chapter(Base):
170170
chapter_number: Mapped[int] = mapped_column(Integer)
171171
description: Mapped[str] = mapped_column(String(256))
172172

173-
work: Mapped["Work"] = relationship("Work", back_populates="chapter")
174-
paragraph: Mapped[list["Paragraph"]] = relationship(
173+
work: Mapped[Work] = relationship("Work", back_populates="chapter")
174+
paragraph: Mapped[list[Paragraph]] = relationship(
175175
"Paragraph", back_populates="chapter"
176176
)
177177

@@ -259,11 +259,9 @@ class Paragraph(Base):
259259
char_count: Mapped[int] = mapped_column(Integer)
260260
word_count: Mapped[int] = mapped_column(Integer)
261261

262-
character: Mapped["Character"] = relationship(
263-
"Character", back_populates="paragraph"
264-
)
265-
chapter: Mapped["Chapter"] = relationship("Chapter", back_populates="paragraph")
266-
work: Mapped["Work"] = relationship("Work", back_populates="paragraph")
262+
character: Mapped[Character] = relationship("Character", back_populates="paragraph")
263+
chapter: Mapped[Chapter] = relationship("Chapter", back_populates="paragraph")
264+
work: Mapped[Work] = relationship("Work", back_populates="paragraph")
267265

268266
@classmethod
269267
async def find(cls, db_session: AsyncSession, character: str):

app/models/stuff.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Stuff(Base):
2929
name: Mapped[str] = mapped_column(String, primary_key=True, unique=True)
3030
description: Mapped[str | None]
3131

32-
nonsense: Mapped["Nonsense"] = relationship(
32+
nonsense: Mapped[Nonsense] = relationship(
3333
"Nonsense", secondary="happy_hog.stuff_full_of_nonsense"
3434
)
3535

@@ -47,7 +47,7 @@ class StuffFullOfNonsense(Base):
4747
UUID(as_uuid=True), default=uuid.uuid4, primary_key=True
4848
)
4949
stuff_id: Mapped[Stuff] = mapped_column(UUID, ForeignKey("happy_hog.stuff.id"))
50-
nonsense_id: Mapped["Nonsense"] = mapped_column(
50+
nonsense_id: Mapped[Nonsense] = mapped_column(
5151
UUID, ForeignKey("happy_hog.nonsense.id")
5252
)
5353
but_why: Mapped[str | None]

app/schemas/shakespeare.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import annotations
2-
31
from typing import Any
42

53
from pydantic import BaseModel

pyproject.toml

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
11
[project]
22
name = "fastapi-sqlalchemy-asyncpg"
3-
version = "0.22.0"
3+
version = "1.22.0"
44
description = "A modern FastAPI application with SQLAlchemy 2.0 and AsyncPG for high-performance async database operations. Features include JWT authentication with Redis token storage, password hashing, connection pooling, data processing with Polars, Rich logging, task scheduling with APScheduler, and Shakespeare datasets integration."
55
readme = "README.md"
6-
requires-python = ">=3.14"
6+
requires-python = "==3.14.0"
77
dependencies = [
8-
"fastapi[all]>=0.116.2",
9-
"pydantic[email]>=2.12.0a1",
10-
"pydantic-settings>=2.10.1",
8+
"fastapi[all]==0.121.2",
9+
"pydantic[email]==2.12.4",
10+
"pydantic-settings==2.12.0",
1111
"sqlalchemy==2.0.44",
12-
"uvicorn==0.38.0",
13-
"asyncpg>=0.30.0",
14-
"alembic>=1.16.5",
15-
"httpx>=0.28.1",
16-
"pytest>=8.4.2",
17-
"pytest-cov>=7.0.0",
18-
"uvloop>=0.21.0",
19-
"httptools>=0.6.4",
20-
"rich>=14.1.0",
21-
"pyjwt>=2.10.1",
22-
"redis>=6.4.0",
23-
"bcrypt>=4.3.0",
24-
"polars==1.35.2",
25-
"python-multipart>=0.0.20",
26-
"fastexcel>=0.15.1",
27-
"inline-snapshot>=0.29.0",
28-
"dirty-equals>=0.10.0",
29-
"polyfactory>=2.22.2",
30-
"granian>=2.5.4",
12+
"uvicorn[standard]==0.38.0",
13+
"asyncpg==0.30.0",
14+
"alembic==1.17.2",
15+
"httpx==0.28.1",
16+
"pytest==9.0.1",
17+
"pytest-cov==7.0.0",
18+
"uvloop==0.22.1",
19+
"httptools==0.7.1",
20+
"rich==14.2.0",
21+
"pyjwt==2.10.1",
22+
"redis==7.0.1",
23+
"bcrypt==5.0.0",
24+
"polars[pyarrow]==1.35.2",
25+
"python-multipart==0.0.20",
26+
"fastexcel==0.16.0",
27+
"inline-snapshot==0.31.1",
28+
"dirty-equals==0.10.0",
29+
"polyfactory==3.0.0",
30+
"granian==2.5.7",
3131
"apscheduler[redis,sqlalchemy]>=4.0.0a6",
3232
"rotoger==0.2.1",
3333
]
3434

3535
[tool.uv]
3636
dev-dependencies = [
37-
"ruff>=0.13.1",
38-
"devtools[pygments]>=0.12.2",
39-
"pyupgrade>=3.20.0",
40-
"ipython>=9.5.0",
41-
"sqlacodegen<=3.1.1",
42-
"tryceratops>=2.4.1",
43-
"locust>=2.40.5"
44-
37+
"ruff==0.14.5",
38+
"devtools[pygments]==0.12.2",
39+
"pyupgrade==3.21.1",
40+
"ipython==9.7.0",
41+
"tryceratops==2.4.1",
4542
]
4643

4744

@@ -50,7 +47,7 @@ strict = true
5047
exclude = ["venv", ".venv", "alembic"]
5148

5249
[tool.ruff]
53-
target-version = "py313"
50+
target-version = "py314"
5451
exclude = ["alembic"]
5552

5653
[tool.ruff.lint]

0 commit comments

Comments
 (0)