Skip to content

Commit 7623d0e

Browse files
committed
bump project deps, inline-snapshot config, add templates
1 parent 241f1c7 commit 7623d0e

File tree

7 files changed

+269
-136
lines changed

7 files changed

+269
-136
lines changed

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ USER panettone
5252
WORKDIR /panettone
5353
COPY /app/ app/
5454
COPY /tests/ tests/
55+
COPY /templates/ templates/
5556
COPY .env app/
5657
COPY alembic.ini app/
5758
COPY alembic/ app/alembic/
5859
COPY logging-uvicorn.json /panettone/logging-uvicorn.json
60+
COPY pyproject.toml /panettone/pyproject.toml
5961

6062
RUN python -V
6163
RUN python -Im site

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ docker-test: ## Run project tests
3131

3232
.PHONY: docker-test-snapshot
3333
docker-test-snapshot: ## Run project tests with inline snapshot
34-
docker compose -f compose.yml -f test-compose.yml run --rm app pytest --inline-snapshot=create
34+
docker compose -f compose.yml -f test-compose.yml run --rm app pytest tests --inline-snapshot=fix
3535

3636
.PHONY: safety
3737
safety: ## Check project and dependencies with safety https://github.com/pyupio/safety

app/main.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
from apscheduler import AsyncScheduler
55
from apscheduler.datastores.sqlalchemy import SQLAlchemyDataStore
66
from apscheduler.eventbrokers.redis import RedisEventBroker
7-
from fastapi import Depends, FastAPI
7+
from fastapi import Depends, FastAPI, Request
8+
from fastapi.responses import HTMLResponse
9+
from fastapi.templating import Jinja2Templates
810

911
from app.api.health import router as health_router
1012
from app.api.ml import router as ml_router
@@ -21,6 +23,8 @@
2123

2224
logger = AppLogger().get_logger()
2325

26+
templates = Jinja2Templates(directory="templates")
27+
2428

2529
@asynccontextmanager
2630
async def lifespan(_app: FastAPI):
@@ -46,7 +50,7 @@ async def lifespan(_app: FastAPI):
4650
await _app.postgres_pool.close()
4751

4852

49-
app = FastAPI(title="Stuff And Nonsense API", version="0.18.0", lifespan=lifespan)
53+
app = FastAPI(title="Stuff And Nonsense API", version="0.19.0", lifespan=lifespan)
5054

5155
app.include_router(stuff_router)
5256
app.include_router(nonsense_router)
@@ -63,13 +67,19 @@ async def lifespan(_app: FastAPI):
6367
dependencies=[Depends(AuthBearer())],
6468
)
6569

66-
_scheduler_data_store = SQLAlchemyDataStore(engine, schema="scheduler")
67-
_scheduler_event_broker = RedisEventBroker(
68-
client_or_url=global_settings.redis_url.unicode_string()
69-
)
70-
_scheduler_himself = AsyncScheduler(_scheduler_data_store, _scheduler_event_broker)
7170

72-
app.add_middleware(SchedulerMiddleware, scheduler=_scheduler_himself)
71+
@app.get("/index", response_class=HTMLResponse)
72+
def get_index(request: Request):
73+
return templates.TemplateResponse("index.html", {"request": request})
74+
75+
76+
# _scheduler_data_store = SQLAlchemyDataStore(engine, schema="scheduler")
77+
# _scheduler_event_broker = RedisEventBroker(
78+
# client_or_url=global_settings.redis_url.unicode_string()
79+
# )
80+
# _scheduler_himself = AsyncScheduler(_scheduler_data_store, _scheduler_event_broker)
81+
#
82+
# app.add_middleware(SchedulerMiddleware, scheduler=_scheduler_himself)
7383

7484

7585
# TODO: every not GET meth should reset cache

compose.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ services:
1414
--reload --log-level debug
1515
"
1616
volumes:
17-
- .:/home/code
17+
- ./app:/panettone/app
18+
- ./tests:/panettone/tests
19+
- ./templates:/panettone/templates
1820
ports:
1921
- "8080:8080"
2022
depends_on:

pyproject.toml

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
[project]
22
name = "fastapi-sqlalchemy-asyncpg"
3-
version = "0.18.0"
3+
version = "0.19.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"
66
requires-python = ">=3.13"
77
dependencies = [
88
"fastapi[all]>=0.115.12",
9-
"pydantic[email]>=2.11.4",
9+
"pydantic[email]>=2.11.5",
1010
"pydantic-settings>=2.9.1",
11-
"sqlalchemy>=2.0.40",
12-
"uvicorn[standard]>=0.34.2",
11+
"sqlalchemy>=2.0.41",
12+
"uvicorn[standard]>=0.34.3",
1313
"asyncpg>=0.30.0",
14-
"alembic>=1.15.2",
14+
"alembic>=1.16.1",
1515
"httpx>=0.28.1",
16-
"pytest>=8.3.5",
16+
"pytest>=8.4.0",
1717
"pytest-cov>=6.1.1",
1818
"uvloop>=0.21.0",
1919
"httptools>=0.6.4",
2020
"rich>=14.0.0",
2121
"pyjwt>=2.10.1",
22-
"redis>=6.0.0",
22+
"redis>=6.2.0",
2323
"bcrypt>=4.3.0",
24-
"polars>=1.29.0",
24+
"polars>=1.30.0",
2525
"python-multipart>=0.0.20",
2626
"fastexcel>=0.14.0",
27-
"inline-snapshot>=0.23.0",
27+
"inline-snapshot>=0.23.2",
2828
"dirty-equals>=0.9.0",
2929
"polyfactory>=2.21.0",
30-
"granian>=2.2.5",
30+
"granian>=2.3.2",
3131
"apscheduler[redis,sqlalchemy]>=4.0.0a6",
3232
]
3333

3434
[tool.uv]
3535
dev-dependencies = [
36-
"ruff>=0.11.8",
36+
"ruff>=0.11.13",
3737
"devtools[pygments]>=0.12.2",
38-
"pyupgrade>=3.19.1",
39-
"ipython>=9.2.0",
38+
"pyupgrade>=3.20.0",
39+
"ipython>=9.3.0",
4040
"sqlacodegen>=3.0.0",
4141
"tryceratops>=2.4.1",
42-
"locust>=2.36.2"
42+
"locust>=2.37.9"
4343

4444
]
4545

@@ -72,4 +72,15 @@ ignore = [
7272

7373
[tool.ruff.lint.pyupgrade]
7474
# Preserve types, even if a file imports `from __future__ import annotations`.
75-
keep-runtime-typing = true
75+
keep-runtime-typing = true
76+
77+
[tool.inline-snapshot]
78+
hash-length=15
79+
default-flags=["report"]
80+
default-flags-tui=["create", "review"]
81+
show-updates=false
82+
format-command="ruff format --stdin-filename {filename}"
83+
84+
[tool.inline-snapshot.shortcuts]
85+
review=["review"]
86+
fix=["create","fix"]

templates/index.html

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
<title>Tabler Demo</title>
8+
<link rel="stylesheet"
9+
href="https://cdn.jsdelivr.net/npm/@tabler/core@1.2.0/dist/css/tabler.min.css" />
10+
</head>
11+
12+
<body>
13+
<header class="navbar navbar-expand-md d-print-none">
14+
<div class="container-xl">
15+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
16+
data-bs-target="#navbar-menu" aria-controls="navbar-menu"
17+
aria-expanded="false" aria-label="Toggle navigation">
18+
<span class="navbar-toggler-icon"></span>
19+
</button>
20+
<!-- BEGIN NAVBAR LOGO --><a href="../../.."
21+
class="navbar-brand navbar-brand-autodark me-3"><svg
22+
xmlns="http://www.w3.org/2000/svg" width="110" height="32"
23+
viewBox="0 0 232 68" class="navbar-brand-image">
24+
<path
25+
d="M64.6 16.2C63 9.9 58.1 5 51.8 3.4 40 1.5 28 1.5 16.2 3.4 9.9 5 5 9.9 3.4 16.2 1.5 28 1.5 40 3.4 51.8 5 58.1 9.9 63 16.2 64.6c11.8 1.9 23.8 1.9 35.6 0C58.1 63 63 58.1 64.6 51.8c1.9-11.8 1.9-23.8 0-35.6zM33.3 36.3c-2.8 4.4-6.6 8.2-11.1 11-1.5.9-3.3.9-4.8.1s-2.4-2.3-2.5-4c0-1.7.9-3.3 2.4-4.1 2.3-1.4 4.4-3.2 6.1-5.3-1.8-2.1-3.8-3.8-6.1-5.3-2.3-1.3-3-4.2-1.7-6.4s4.3-2.9 6.5-1.6c4.5 2.8 8.2 6.5 11.1 10.9 1 1.4 1 3.3.1 4.7zM49.2 46H37.8c-2.1 0-3.8-1-3.8-3s1.7-3 3.8-3h11.4c2.1 0 3.8 1 3.8 3s-1.7 3-3.8 3z"
26+
fill="#066fd1" style="fill: var(--tblr-primary, #066fd1)" />
27+
<path
28+
d="M105.8 46.1c.4 0 .9.2 1.2.6s.6 1 .6 1.7c0 .9-.5 1.6-1.4 2.2s-2 .9-3.2.9c-2 0-3.7-.4-5-1.3s-2-2.6-2-5.4V31.6h-2.2c-.8 0-1.4-.3-1.9-.8s-.9-1.1-.9-1.9c0-.7.3-1.4.8-1.8s1.2-.7 1.9-.7h2.2v-3.1c0-.8.3-1.5.8-2.1s1.3-.8 2.1-.8 1.5.3 2 .8.8 1.3.8 2.1v3.1h3.4c.8 0 1.4.3 1.9.8s.8 1.2.8 1.9-.3 1.4-.8 1.8-1.2.7-1.9.7h-3.4v13c0 .7.2 1.2.5 1.5s.8.5 1.4.5c.3 0 .6-.1 1.1-.2.5-.2.8-.3 1.2-.3zm28-20.7c.8 0 1.5.3 2.1.8.5.5.8 1.2.8 2.1v20.3c0 .8-.3 1.5-.8 2.1-.5.6-1.2.8-2.1.8s-1.5-.3-2-.8-.8-1.2-.8-2.1c-.8.9-1.9 1.7-3.2 2.4-1.3.7-2.8 1-4.3 1-2.2 0-4.2-.6-6-1.7-1.8-1.1-3.2-2.7-4.2-4.7s-1.6-4.3-1.6-6.9c0-2.6.5-4.9 1.5-6.9s2.4-3.6 4.2-4.8c1.8-1.1 3.7-1.7 5.9-1.7 1.5 0 3 .3 4.3.8 1.3.6 2.5 1.3 3.4 2.1 0-.8.3-1.5.8-2.1.5-.5 1.2-.7 2-.7zm-9.7 21.3c2.1 0 3.8-.8 5.1-2.3s2-3.4 2-5.7-.7-4.2-2-5.8c-1.3-1.5-3-2.3-5.1-2.3-2 0-3.7.8-5 2.3-1.3 1.5-2 3.5-2 5.8s.6 4.2 1.9 5.7 3 2.3 5.1 2.3zm32.1-21.3c2.2 0 4.2.6 6 1.7 1.8 1.1 3.2 2.7 4.2 4.7s1.6 4.3 1.6 6.9-.5 4.9-1.5 6.9-2.4 3.6-4.2 4.8c-1.8 1.1-3.7 1.7-5.9 1.7-1.5 0-3-.3-4.3-.9s-2.5-1.4-3.4-2.3v.3c0 .8-.3 1.5-.8 2.1-.5.6-1.2.8-2.1.8s-1.5-.3-2.1-.8c-.5-.5-.8-1.2-.8-2.1V18.9c0-.8.3-1.5.8-2.1.5-.6 1.2-.8 2.1-.8s1.5.3 2.1.8c.5.6.8 1.3.8 2.1v10c.8-1 1.8-1.8 3.2-2.5 1.3-.7 2.8-1 4.3-1zm-.7 21.3c2 0 3.7-.8 5-2.3s2-3.5 2-5.8-.6-4.2-1.9-5.7-3-2.3-5.1-2.3-3.8.8-5.1 2.3-2 3.4-2 5.7.7 4.2 2 5.8c1.3 1.6 3 2.3 5.1 2.3zm23.6 1.9c0 .8-.3 1.5-.8 2.1s-1.3.8-2.1.8-1.5-.3-2-.8-.8-1.3-.8-2.1V18.9c0-.8.3-1.5.8-2.1s1.3-.8 2.1-.8 1.5.3 2 .8.8 1.3.8 2.1v29.7zm29.3-10.5c0 .8-.3 1.4-.9 1.9-.6.5-1.2.7-2 .7h-15.8c.4 1.9 1.3 3.4 2.6 4.4 1.4 1.1 2.9 1.6 4.7 1.6 1.3 0 2.3-.1 3.1-.4.7-.2 1.3-.5 1.8-.8.4-.3.7-.5.9-.6.6-.3 1.1-.4 1.6-.4.7 0 1.2.2 1.7.7s.7 1 .7 1.7c0 .9-.4 1.6-1.3 2.4-.9.7-2.1 1.4-3.6 1.9s-3 .8-4.6.8c-2.7 0-5-.6-7-1.7s-3.5-2.7-4.6-4.6-1.6-4.2-1.6-6.6c0-2.8.6-5.2 1.7-7.2s2.7-3.7 4.6-4.8 3.9-1.7 6-1.7 4.1.6 6 1.7 3.4 2.7 4.5 4.7c.9 1.9 1.5 4.1 1.5 6.3zm-12.2-7.5c-3.7 0-5.9 1.7-6.6 5.2h12.6v-.3c-.1-1.3-.8-2.5-2-3.5s-2.5-1.4-4-1.4zm30.3-5.2c1 0 1.8.3 2.4.8.7.5 1 1.2 1 1.9 0 1-.3 1.7-.8 2.2-.5.5-1.1.8-1.8.7-.5 0-1-.1-1.6-.3-.2-.1-.4-.1-.6-.2-.4-.1-.7-.1-1.1-.1-.8 0-1.6.3-2.4.8s-1.4 1.3-1.9 2.3-.7 2.3-.7 3.7v11.4c0 .8-.3 1.5-.8 2.1-.5.6-1.2.8-2.1.8s-1.5-.3-2.1-.8c-.5-.6-.8-1.3-.8-2.1V28.8c0-.8.3-1.5.8-2.1.5-.6 1.2-.8 2.1-.8s1.5.3 2.1.8c.5.6.8 1.3.8 2.1v.6c.7-1.3 1.8-2.3 3.2-3 1.3-.7 2.8-1 4.3-1z"
29+
fill-rule="evenodd" clip-rule="evenodd" fill="#4a4a4a" />
30+
</svg></a><!-- END NAVBAR LOGO -->
31+
<ul class="navbar-nav">
32+
<li class="nav-item active">
33+
<a class="nav-link" href="#">
34+
<span class="nav-link-icon">
35+
<!-- Download SVG icon from http://tabler.io/icons/icon/home -->
36+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
37+
viewBox="0 0 24 24" fill="none" stroke="currentColor"
38+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
39+
class="icon icon-1">
40+
<path d="M5 12l-2 0l9 -9l9 9l-2 0" />
41+
<path d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7" />
42+
<path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6" />
43+
</svg>
44+
</span>
45+
<span class="nav-link-title"> Home </span>
46+
</a>
47+
</li>
48+
<li class="nav-item">
49+
<a class="nav-link" href="#">
50+
<span
51+
class="nav-link-icon"><!-- Download SVG icon from http://tabler.io/icons/icon/checkbox -->
52+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
53+
viewBox="0 0 24 24" fill="none" stroke="currentColor"
54+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
55+
class="icon icon-1">
56+
<path d="M9 11l3 3l8 -8" />
57+
<path
58+
d="M20 12v6a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h9" />
59+
</svg>
60+
</span>
61+
<span class="nav-link-title"> Profile </span>
62+
</a>
63+
</li>
64+
<li class="nav-item">
65+
<a class="nav-link" href="#">
66+
<span
67+
class="nav-link-icon"><!-- Download SVG icon from http://tabler.io/icons/icon/checkbox -->
68+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"
69+
viewBox="0 0 24 24" fill="none" stroke="currentColor"
70+
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
71+
class="icon icon-1">
72+
<path d="M9 11l3 3l8 -8" />
73+
<path
74+
d="M20 12v6a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h9" />
75+
</svg>
76+
</span>
77+
<span class="nav-link-title"> Settings </span>
78+
</a>
79+
</li>
80+
</ul>
81+
<div class="navbar-nav flex-row order-md-last ms-auto">
82+
<div class="nav-item dropdown">
83+
<a href="#" class="nav-link d-flex lh-1 text-reset"
84+
data-bs-toggle="dropdown" aria-label="Open user menu">
85+
<span class="avatar avatar-sm"
86+
style="background-image: url(/static/avatars/044m.jpg)"></span>
87+
<div class="d-none d-xl-block ps-2">
88+
<div>Paweł Kuna</div>
89+
<div class="mt-1 small text-secondary">UI Designer</div>
90+
</div>
91+
</a>
92+
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
93+
<a href="#" class="dropdown-item">Status</a>
94+
<a href="./profile.html" class="dropdown-item">Profile</a>
95+
<a href="#" class="dropdown-item">Feedback</a>
96+
<div class="dropdown-divider"></div>
97+
<a href="./settings.html" class="dropdown-item">Settings</a>
98+
<a href="./sign-in.html" class="dropdown-item">Logout</a>
99+
</div>
100+
</div>
101+
</div>
102+
</div>
103+
</header>
104+
</body>
105+
106+
</html>

0 commit comments

Comments
 (0)