Skip to content

Commit 0cc802e

Browse files
authored
🎨 Format files with pre-commit and Ruff (#611)
1 parent 2802a4d commit 0cc802e

35 files changed

+156
-163
lines changed

.github/workflows/test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727

2828
- name: Run tests
2929
run: docker compose build
30-
- name: Docker Compose remove old containers and volumes
30+
- name: Docker Compose remove old containers and volumes
3131
run: docker compose down -v --remove-orphans
3232
- name: Docker Compose up
3333
run: docker compose up -d

src/backend/app/alembic/README

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Generic single-database configuration.
1+
Generic single-database configuration.

src/backend/app/alembic/env.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
from __future__ import with_statement
2-
31
import os
2+
from logging.config import fileConfig
43

54
from alembic import context
65
from sqlalchemy import engine_from_config, pool
7-
from logging.config import fileConfig
86

97
# this is the Alembic Config object, which provides
108
# access to the values within the .ini file in use.
@@ -69,7 +67,9 @@ def run_migrations_online():
6967
configuration = config.get_section(config.config_ini_section)
7068
configuration["sqlalchemy.url"] = get_url()
7169
connectable = engine_from_config(
72-
configuration, prefix="sqlalchemy.", poolclass=pool.NullPool,
70+
configuration,
71+
prefix="sqlalchemy.",
72+
poolclass=pool.NullPool,
7373
)
7474

7575
with connectable.connect() as connection:
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,54 @@
11
"""Initialize models
22
33
Revision ID: e2412789c190
4-
Revises:
4+
Revises:
55
Create Date: 2023-11-24 22:55:43.195942
66
77
"""
8-
from alembic import op
98
import sqlalchemy as sa
109
import sqlmodel.sql.sqltypes
11-
10+
from alembic import op
1211

1312
# revision identifiers, used by Alembic.
14-
revision = 'e2412789c190'
13+
revision = "e2412789c190"
1514
down_revision = None
1615
branch_labels = None
1716
depends_on = None
1817

1918

2019
def upgrade():
2120
# ### commands auto generated by Alembic - please adjust! ###
22-
op.create_table('user',
23-
sa.Column('email', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
24-
sa.Column('is_active', sa.Boolean(), nullable=False),
25-
sa.Column('is_superuser', sa.Boolean(), nullable=False),
26-
sa.Column('full_name', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
27-
sa.Column('id', sa.Integer(), nullable=False),
28-
sa.Column('hashed_password', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
29-
sa.PrimaryKeyConstraint('id')
21+
op.create_table(
22+
"user",
23+
sa.Column("email", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
24+
sa.Column("is_active", sa.Boolean(), nullable=False),
25+
sa.Column("is_superuser", sa.Boolean(), nullable=False),
26+
sa.Column("full_name", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
27+
sa.Column("id", sa.Integer(), nullable=False),
28+
sa.Column(
29+
"hashed_password", sqlmodel.sql.sqltypes.AutoString(), nullable=False
30+
),
31+
sa.PrimaryKeyConstraint("id"),
3032
)
31-
op.create_index(op.f('ix_user_email'), 'user', ['email'], unique=True)
32-
op.create_table('item',
33-
sa.Column('description', sqlmodel.sql.sqltypes.AutoString(), nullable=True),
34-
sa.Column('id', sa.Integer(), nullable=False),
35-
sa.Column('title', sqlmodel.sql.sqltypes.AutoString(), nullable=False),
36-
sa.Column('owner_id', sa.Integer(), nullable=False),
37-
sa.ForeignKeyConstraint(['owner_id'], ['user.id'], ),
38-
sa.PrimaryKeyConstraint('id')
33+
op.create_index(op.f("ix_user_email"), "user", ["email"], unique=True)
34+
op.create_table(
35+
"item",
36+
sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
37+
sa.Column("id", sa.Integer(), nullable=False),
38+
sa.Column("title", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
39+
sa.Column("owner_id", sa.Integer(), nullable=False),
40+
sa.ForeignKeyConstraint(
41+
["owner_id"],
42+
["user.id"],
43+
),
44+
sa.PrimaryKeyConstraint("id"),
3945
)
4046
# ### end Alembic commands ###
4147

4248

4349
def downgrade():
4450
# ### commands auto generated by Alembic - please adjust! ###
45-
op.drop_table('item')
46-
op.drop_index(op.f('ix_user_email'), table_name='user')
47-
op.drop_table('user')
51+
op.drop_table("item")
52+
op.drop_index(op.f("ix_user_email"), table_name="user")
53+
op.drop_table("user")
4854
# ### end Alembic commands ###

src/backend/app/api/api_v1/endpoints/items.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from typing import Any
22

33
from fastapi import APIRouter, HTTPException
4-
from sqlmodel import select, func
4+
from sqlmodel import func, select
55

66
from app.api.deps import CurrentUser, SessionDep
7-
from app.models import Item, ItemCreate, ItemOut, ItemUpdate, Message, ItemsOut
7+
from app.models import Item, ItemCreate, ItemOut, ItemsOut, ItemUpdate, Message
88

99
router = APIRouter()
1010

@@ -22,7 +22,7 @@ def read_items(
2222

2323
if current_user.is_superuser:
2424
statement = select(Item).offset(skip).limit(limit)
25-
items = session.exec(statement).all()
25+
items = session.exec(statement).all()
2626
else:
2727
statement = (
2828
select(Item)

src/backend/app/api/api_v1/endpoints/users.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
from typing import Any, List
1+
from typing import Any
22

33
from fastapi import APIRouter, Depends, HTTPException
4-
from sqlmodel import select, func
4+
from sqlmodel import func, select
55

66
from app import crud
77
from app.api.deps import (
@@ -28,9 +28,7 @@
2828

2929

3030
@router.get(
31-
"/",
32-
dependencies=[Depends(get_current_active_superuser)],
33-
response_model=UsersOut
31+
"/", dependencies=[Depends(get_current_active_superuser)], response_model=UsersOut
3432
)
3533
def read_users(session: SessionDep, skip: int = 0, limit: int = 100) -> Any:
3634
"""

src/backend/app/api/deps.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Annotated, Generator
1+
from collections.abc import Generator
2+
from typing import Annotated
23

34
from fastapi import Depends, HTTPException, status
45
from fastapi.security import OAuth2PasswordBearer

src/backend/app/core/config.py

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import secrets
2-
from typing import Any, Dict, List, Optional, Union
2+
from typing import Any
33

44
from pydantic import AnyHttpUrl, BaseSettings, EmailStr, HttpUrl, PostgresDsn, validator
55

@@ -14,21 +14,21 @@ class Settings(BaseSettings):
1414
# BACKEND_CORS_ORIGINS is a JSON-formatted list of origins
1515
# e.g: '["http://localhost", "http://localhost:4200", "http://localhost:3000", \
1616
# "http://localhost:8080", "http://local.dockertoolbox.tiangolo.com"]'
17-
BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = []
17+
BACKEND_CORS_ORIGINS: list[AnyHttpUrl] = []
1818

1919
@validator("BACKEND_CORS_ORIGINS", pre=True)
20-
def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]:
20+
def assemble_cors_origins(cls, v: str | list[str]) -> list[str] | str:
2121
if isinstance(v, str) and not v.startswith("["):
2222
return [i.strip() for i in v.split(",")]
23-
elif isinstance(v, (list, str)):
23+
elif isinstance(v, list | str):
2424
return v
2525
raise ValueError(v)
2626

2727
PROJECT_NAME: str
28-
SENTRY_DSN: Optional[HttpUrl] = None
28+
SENTRY_DSN: HttpUrl | None = None
2929

3030
@validator("SENTRY_DSN", pre=True)
31-
def sentry_dsn_can_be_blank(cls, v: str) -> Optional[str]:
31+
def sentry_dsn_can_be_blank(cls, v: str) -> str | None:
3232
if len(v) == 0:
3333
return None
3434
return v
@@ -37,10 +37,10 @@ def sentry_dsn_can_be_blank(cls, v: str) -> Optional[str]:
3737
POSTGRES_USER: str
3838
POSTGRES_PASSWORD: str
3939
POSTGRES_DB: str
40-
SQLALCHEMY_DATABASE_URI: Optional[PostgresDsn] = None
40+
SQLALCHEMY_DATABASE_URI: PostgresDsn | None = None
4141

4242
@validator("SQLALCHEMY_DATABASE_URI", pre=True)
43-
def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any:
43+
def assemble_db_connection(cls, v: str | None, values: dict[str, Any]) -> Any:
4444
if isinstance(v, str):
4545
return v
4646
return PostgresDsn.build(
@@ -52,15 +52,15 @@ def assemble_db_connection(cls, v: Optional[str], values: Dict[str, Any]) -> Any
5252
)
5353

5454
SMTP_TLS: bool = True
55-
SMTP_PORT: Optional[int] = None
56-
SMTP_HOST: Optional[str] = None
57-
SMTP_USER: Optional[str] = None
58-
SMTP_PASSWORD: Optional[str] = None
59-
EMAILS_FROM_EMAIL: Optional[EmailStr] = None
60-
EMAILS_FROM_NAME: Optional[str] = None
55+
SMTP_PORT: int | None = None
56+
SMTP_HOST: str | None = None
57+
SMTP_USER: str | None = None
58+
SMTP_PASSWORD: str | None = None
59+
EMAILS_FROM_EMAIL: EmailStr | None = None
60+
EMAILS_FROM_NAME: str | None = None
6161

6262
@validator("EMAILS_FROM_NAME")
63-
def get_project_name(cls, v: Optional[str], values: Dict[str, Any]) -> str:
63+
def get_project_name(cls, v: str | None, values: dict[str, Any]) -> str:
6464
if not v:
6565
return values["PROJECT_NAME"]
6666
return v
@@ -70,7 +70,7 @@ def get_project_name(cls, v: Optional[str], values: Dict[str, Any]) -> str:
7070
EMAILS_ENABLED: bool = False
7171

7272
@validator("EMAILS_ENABLED", pre=True)
73-
def get_emails_enabled(cls, v: bool, values: Dict[str, Any]) -> bool:
73+
def get_emails_enabled(cls, v: bool, values: dict[str, Any]) -> bool:
7474
return bool(
7575
values.get("SMTP_HOST")
7676
and values.get("SMTP_PORT")

src/backend/app/core/security.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from datetime import datetime, timedelta
2-
from typing import Any, Union
2+
from typing import Any
33

44
from jose import jwt
55
from passlib.context import CryptContext
@@ -12,9 +12,7 @@
1212
ALGORITHM = "HS256"
1313

1414

15-
def create_access_token(
16-
subject: Union[str, Any], expires_delta: timedelta = None
17-
) -> str:
15+
def create_access_token(subject: str | Any, expires_delta: timedelta = None) -> str:
1816
if expires_delta:
1917
expire = datetime.utcnow() + expires_delta
2018
else:

src/backend/app/crud/__init__.py

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
from .crud_item import item
2-
from .crud_user import user
3-
41
# For a new basic set of CRUD operations you could just do
5-
62
# from .base import CRUDBase
73
# from app.models.item import Item
84
# from app.schemas.item import ItemCreate, ItemUpdate
9-
105
# item = CRUDBase[Item, ItemCreate, ItemUpdate](Item)
116
from sqlmodel import Session, select
7+
128
from app.core.security import get_password_hash, verify_password
13-
from app.models import UserCreate, User
9+
from app.models import User, UserCreate
10+
11+
from .crud_item import item as item
12+
from .crud_user import user as user
1413

1514

1615
def create_user(*, session: Session, user_create: UserCreate) -> User:
@@ -30,9 +29,9 @@ def get_user_by_email(*, session: Session, email: str) -> User | None:
3029

3130

3231
def authenticate(*, session: Session, email: str, password: str) -> User | None:
33-
user = get_user_by_email(session=session, email=email)
34-
if not user:
32+
db_user = get_user_by_email(session=session, email=email)
33+
if not db_user:
3534
return None
36-
if not verify_password(password, user.hashed_password):
35+
if not verify_password(password, db_user.hashed_password):
3736
return None
38-
return user
37+
return db_user

src/backend/app/crud/base.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, Generic, List, Optional, Type, TypeVar, Union
1+
from typing import Any, Generic, TypeVar
22

33
from fastapi.encoders import jsonable_encoder
44
from pydantic import BaseModel
@@ -10,7 +10,7 @@
1010

1111

1212
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
13-
def __init__(self, model: Type[ModelType]):
13+
def __init__(self, model: type[ModelType]):
1414
"""
1515
CRUD object with default methods to Create, Read, Update, Delete (CRUD).
1616
@@ -21,7 +21,7 @@ def __init__(self, model: Type[ModelType]):
2121
"""
2222
self.model = model
2323

24-
def get(self, db: Session, id: Any) -> Optional[ModelType]:
24+
def get(self, db: Session, id: Any) -> ModelType | None:
2525
return db.query(self.model).filter(self.model.id == id).first()
2626

2727
def create(self, db: Session, *, obj_in: CreateSchemaType) -> ModelType:
@@ -37,7 +37,7 @@ def update(
3737
db: Session,
3838
*,
3939
db_obj: ModelType,
40-
obj_in: Union[UpdateSchemaType, Dict[str, Any]]
40+
obj_in: UpdateSchemaType | dict[str, Any],
4141
) -> ModelType:
4242
obj_data = jsonable_encoder(db_obj)
4343
if isinstance(obj_in, dict):

src/backend/app/crud/crud_item.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from typing import List
2-
31
from fastapi.encoders import jsonable_encoder
42
from sqlalchemy.orm import Session
53

@@ -21,7 +19,7 @@ def create_with_owner(
2119

2220
def get_multi_by_owner(
2321
self, db: Session, *, owner_id: int, skip: int = 0, limit: int = 100
24-
) -> List[Item]:
22+
) -> list[Item]:
2523
return (
2624
db.query(self.model)
2725
.filter(Item.owner_id == owner_id)

src/backend/app/crud/crud_user.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict, Optional, Union
1+
from typing import Any
22

33
from sqlalchemy.orm import Session
44

@@ -9,7 +9,7 @@
99

1010

1111
class CRUDUser(CRUDBase[User, UserCreate, UserUpdate]):
12-
def get_by_email(self, db: Session, *, email: str) -> Optional[User]:
12+
def get_by_email(self, db: Session, *, email: str) -> User | None:
1313
return db.query(User).filter(User.email == email).first()
1414

1515
def create(self, db: Session, *, obj_in: UserCreate) -> User:
@@ -25,7 +25,7 @@ def create(self, db: Session, *, obj_in: UserCreate) -> User:
2525
return db_obj
2626

2727
def update(
28-
self, db: Session, *, db_obj: User, obj_in: Union[UserUpdate, Dict[str, Any]]
28+
self, db: Session, *, db_obj: User, obj_in: UserUpdate | dict[str, Any]
2929
) -> User:
3030
if isinstance(obj_in, dict):
3131
update_data = obj_in
@@ -37,7 +37,7 @@ def update(
3737
update_data["hashed_password"] = hashed_password
3838
return super().update(db, db_obj=db_obj, obj_in=update_data)
3939

40-
def authenticate(self, db: Session, *, email: str, password: str) -> Optional[User]:
40+
def authenticate(self, db: Session, *, email: str, password: str) -> User | None:
4141
user = self.get_by_email(db, email=email)
4242
if not user:
4343
return None

src/backend/app/email-templates/build/new_account.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323
.mj-column-per-100 { width:100% !important; max-width: 100%; }
2424
}</style><style type="text/css"></style></head><body style="background-color:#ffffff;"><div style="background-color:#ffffff;"><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]--><div style="Margin:0px auto;max-width:600px;"><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;"><tbody><tr><td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;vertical-align:top;"><!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]--><div class="mj-column-per-100 outlook-group-fix" style="font-size:13px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%"><tr><td style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 4px #555555;font-size:1;margin:0px auto;width:100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 4px #555555;font-size:1;margin:0px auto;width:550px;" role="presentation" width="550px" ><tr><td style="height:0;line-height:0;"> &nbsp;
2525
</td></tr></table><![endif]--></td></tr><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:helvetica;font-size:20px;line-height:1;text-align:left;color:#555555;">{{ project_name }} - New Account</div></td></tr><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#555555;">You have a new account:</div></td></tr><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#555555;">Username: {{ username }}</div></td></tr><tr><td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;"><div style="font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:16px;line-height:1;text-align:left;color:#555555;">Password: {{ password }}</div></td></tr><tr><td align="center" vertical-align="middle" style="font-size:0px;padding:50px 0px;word-break:break-word;"><table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:separate;line-height:100%;"><tr><td align="center" bgcolor="#414141" role="presentation" style="border:none;border-radius:3px;cursor:auto;padding:10px 25px;background:#414141;" valign="middle"><a href="{{ link }}" style="background:#414141;color:#ffffff;font-family:Ubuntu, Helvetica, Arial, sans-serif;font-size:13px;font-weight:normal;line-height:120%;Margin:0;text-decoration:none;text-transform:none;" target="_blank">Go to Dashboard</a></td></tr></table></td></tr><tr><td style="font-size:0px;padding:10px 25px;word-break:break-word;"><p style="border-top:solid 2px #555555;font-size:1;margin:0px auto;width:100%;"></p><!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" style="border-top:solid 2px #555555;font-size:1;margin:0px auto;width:550px;" role="presentation" width="550px" ><tr><td style="height:0;line-height:0;"> &nbsp;
26-
</td></tr></table><![endif]--></td></tr></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>
26+
</td></tr></table><![endif]--></td></tr></table></div><!--[if mso | IE]></td></tr></table><![endif]--></td></tr></tbody></table></div><!--[if mso | IE]></td></tr></table><![endif]--></div></body></html>

0 commit comments

Comments
 (0)