Skip to content

Commit 1be7240

Browse files
committed
adjusted the code according to latest Python and FastAPI annotation improvements
1 parent 0f50edb commit 1be7240

File tree

7 files changed

+40
-42
lines changed

7 files changed

+40
-42
lines changed

setup.cfg

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ install_requires =
3535
rawpy==0.17.3
3636
Pillow==9.4.0
3737
pydantic==1.10.4
38+
tzdata==2022.7
3839
# The usage of test_requires is discouraged, see `Dependency Management` docs
3940
# tests_require = pytest; pytest-cov
4041
# Require a specific Python version, e.g. Python 2.7 or >= 3.4
@@ -51,17 +52,17 @@ exclude =
5152
# PDF = ReportLab; RXP
5253
# Add here test requirements (semicolon/line-separated)
5354
desktop =
54-
PySide6-Essentials==6.4.1
55+
PySide6-Essentials==6.4.2
5556
web =
5657
alembic==1.9.1
5758
asyncpg==0.27.0
5859
Authlib==1.2.0
5960
passlib==1.7.4
6061
databases[postgresql]==0.7.0
61-
fastapi==0.89.0
62-
fastapi-pagination==0.11.1
62+
fastapi==0.89.1
63+
fastapi-pagination==0.11.2
6364
fastapi-users[sqlalchemy]==10.2.1
64-
orjson==3.8.4
65+
orjson==3.8.5
6566
PyJWT==2.6.0
6667
python-dateutil==2.8.2
6768
SQLAlchemy==1.4.46

src/dataset_image_annotator/__main__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
from collections import defaultdict
55
from pathlib import Path
6-
from typing import Sequence, Union, Optional, Mapping
6+
from typing import Sequence, Union, Mapping
77

88
import rawpy
99
from PySide6.QtCore import QFile, QIODevice, QDir, QFileInfo, QModelIndex, Qt, QStringListModel
@@ -37,7 +37,7 @@ def list_dir_images(path: Path) -> Sequence[Path]:
3737
return list_dir(path, '*.ARW')
3838

3939

40-
def list_dir_metadata(path: Path) -> Optional[Sequence[Path]]:
40+
def list_dir_metadata(path: Path) -> Sequence[Path] | None:
4141
metadata_dir_path = Path(path, '.metadata')
4242

4343
if metadata_dir_path.exists():
@@ -116,7 +116,7 @@ class MainWindow:
116116
def __init__(self, data_root_path: Path):
117117
self.data_root_path = None
118118
self.metadata = defaultdict(dict)
119-
self.selected_file_name: Optional[str] = None
119+
self.selected_file_name: str | None = None
120120
self.types = set()
121121
self.makes = set()
122122
self.models = set()

src/dataset_image_annotator/api/users.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import contextlib
22
import logging
33
import uuid
4-
from typing import Optional
54

65
from fastapi import Request, Depends
76
from fastapi_users import BaseUserManager, UUIDIDMixin
@@ -16,16 +15,16 @@
1615

1716

1817
class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):
19-
reset_password_token_secret = settings.auth_secret
20-
verification_token_secret = settings.auth_secret
18+
reset_password_token_secret = settings.auth_secret.get_secret_value()
19+
verification_token_secret = settings.auth_secret.get_secret_value()
2120

22-
async def on_after_register(self, user: User, request: Optional[Request] = None):
21+
async def on_after_register(self, user: User, request: Request | None = None):
2322
logger.info(f'User {user.id} has registered.')
2423

25-
async def on_after_forgot_password(self, user: User, token: str, request: Optional[Request] = None):
24+
async def on_after_forgot_password(self, user: User, token: str, request: Request | None = None):
2625
logger.info(f'User {user.id} has forgot their password. Reset token: {token}')
2726

28-
async def on_after_request_verify(self, user: User, token: str, request: Optional[Request] = None):
27+
async def on_after_request_verify(self, user: User, token: str, request: Request | None = None):
2928
logger.info(f'Verification requested for user {user.id}. Verification token: {token}')
3029

3130

src/dataset_image_annotator/api/v1/endpoints.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import uuid
33
from functools import wraps
44
from inspect import signature
5-
from typing import Optional, Any, List
5+
from typing import Sequence
66

77
from fastapi import APIRouter, HTTPException, status, Depends, UploadFile, File
88
from fastapi.responses import ORJSONResponse
@@ -29,7 +29,7 @@
2929

3030

3131
def get_jwt_strategy() -> JWTStrategy:
32-
return JWTStrategy(secret=settings.auth_secret, lifetime_seconds=3600)
32+
return JWTStrategy(secret=settings.auth_secret.get_secret_value(), lifetime_seconds=3600)
3333

3434

3535
auth_backend = AuthenticationBackend(name='cluserauth', transport=cookie_transport, get_strategy=get_jwt_strategy)
@@ -77,19 +77,19 @@ async def wrapper(*args, **kwargs):
7777
return wrapper
7878

7979

80-
@router.get('/users', response_model=Page[UserItem], response_class=ORJSONResponse, tags=['Admin'])
80+
@router.get('/users', response_class=ORJSONResponse, tags=['Admin'])
8181
@handle_exceptions
82-
async def get_users(search: Optional[Json] = None, order_by: Optional[str] = None,
83-
user=Depends(get_current_user)):
82+
async def get_users(search: Json | None = None, order_by: str | None = None,
83+
user=Depends(get_current_user)) -> Page[UserItem]:
8484
if user.is_superuser:
8585
return await core.get_users(database, search, order_by)
8686

8787
raise HTTPException(status_code=403)
8888

8989

90-
@router.post('/users', response_model=UserItem, response_class=ORJSONResponse, tags=['Admin'])
90+
@router.post('/users', response_class=ORJSONResponse, tags=['Admin'])
9191
@handle_exceptions
92-
async def create_user(new_user: UserCreate, user=Depends(get_current_user)):
92+
async def create_user(new_user: UserCreate, user=Depends(get_current_user)) -> UserItem:
9393
if user.is_superuser:
9494
created_user = await users.create_user(new_user)
9595

@@ -98,10 +98,10 @@ async def create_user(new_user: UserCreate, user=Depends(get_current_user)):
9898
raise HTTPException(status_code=403)
9999

100100

101-
@router.get('/user-groups', response_model=List[UserGroup], response_class=ORJSONResponse, tags=['Admin'])
101+
@router.get('/user-groups', response_class=ORJSONResponse, tags=['Admin'])
102102
@handle_exceptions
103-
async def get_user_groups(search: Optional[Json[Any]] = None, order_by: Optional[str] = None,
104-
user=Depends(get_current_user)):
103+
async def get_user_groups(search: Json | None = None, order_by: str | None = None,
104+
user=Depends(get_current_user)) -> Sequence[UserGroup]:
105105
if user.is_active:
106106
return await core.get_user_groups(database, search, order_by)
107107

@@ -110,7 +110,7 @@ async def get_user_groups(search: Optional[Json[Any]] = None, order_by: Optional
110110

111111
@router.post('/raw-file', response_class=ORJSONResponse, tags=['Admin'])
112112
@handle_exceptions
113-
async def upload_raw_file(image_file: UploadFile = File(...)):
113+
async def upload_raw_file(image_file: UploadFile = File(...)) -> bool:
114114
if not image_file.filename:
115115
raise HTTPException(status_code=400, detail='Missing file')
116116

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
import uuid
2-
from typing import Optional
32

43
from fastapi_users import schemas
54
from pydantic import BaseModel, UUID4
65

76

87
class UserRead(schemas.BaseUser[uuid.UUID]):
9-
group_id: Optional[int] = None
8+
group_id: int | None = None
109

1110

1211
class UserCreate(schemas.BaseUserCreate):
13-
group_id: Optional[int] = None
12+
group_id: int | None = None
1413

1514

1615
class UserUpdate(schemas.BaseUserUpdate):
17-
group_id: Optional[int] = None
16+
group_id: int | None = None
1817

1918

2019
class UserGroupSearchParams(BaseModel):
21-
name: Optional[str]
20+
name: str | None
2221

2322

2423
class UserGroup(BaseModel):
@@ -29,7 +28,7 @@ class UserGroup(BaseModel):
2928
class UserItem(BaseModel):
3029
id: UUID4
3130
email: str
32-
group_id: Optional[int]
31+
group_id: int | None
3332
is_active: bool
3433
is_superuser: bool
3534
is_verified: bool

src/dataset_image_annotator/conf.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
from typing import Optional
2-
3-
from pydantic import BaseSettings
1+
from pydantic import BaseSettings, PostgresDsn, SecretStr
42

53

64
class Settings(BaseSettings):
75
logging_level: str = 'INFO'
86
logging_format: str = '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
9-
db_dsn: Optional[str] = None
7+
db_dsn: PostgresDsn = None
108
service_addr: str = '127.0.0.1'
119
service_port: int = 8080
1210
alembic_auto_upgrade: bool = False
1311
alembic_config: str = 'alembic.ini'
14-
bootstrap_user_email: Optional[str] = None
15-
auth_secret: str = 'TODO-REPLACE'
12+
bootstrap_user_email: str | None = None
13+
auth_secret: SecretStr = 'TODO-REPLACE'
14+
timezone: str = 'UTC'
1615

1716

1817
settings = Settings()

src/dataset_image_annotator/core.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
import gettext
22
import logging
33
from pathlib import Path
4-
from typing import Mapping, Optional, Sequence
4+
from typing import Mapping, Sequence
55

66
import sqlalchemy as sa
77
from databases.backends.postgres import Record
8-
from fastapi_pagination.bases import AbstractPage
8+
from fastapi_pagination import Page
99
from fastapi_pagination.ext.databases import paginate
1010

11+
from dataset_image_annotator.api.v1.schemas import UserItem
1112
from dataset_image_annotator.db.models import UserGroup, User
1213

1314
logger = logging.getLogger(__name__)
1415
t = gettext.translation('base', Path(Path(__file__).parent, 'locale'), fallback=True, languages=['lv_LV'])
1516
_ = t.gettext
1617

1718

18-
async def get_users(database, search: Optional[Mapping[str, str]] = None,
19-
order_by: Optional[str] = None) -> AbstractPage[Record]:
19+
async def get_users(database, search: Mapping[str, str] | None = None, order_by: str | None = None) -> Page[UserItem]:
2020
query = sa.select([User])
2121
result = await paginate(database, query)
2222

@@ -29,8 +29,8 @@ async def get_user(database, user_id: str) -> Record:
2929
return await database.fetch_row(query)
3030

3131

32-
async def get_user_groups(database, search: Optional[Mapping[str, str]] = None,
33-
order_by: Optional[str] = None) -> Sequence[Record]:
32+
async def get_user_groups(database, search: Mapping[str, str] | None = None,
33+
order_by: str | None = None) -> Sequence[UserGroup]:
3434
query = sa.select([UserGroup]).order_by(UserGroup.name)
3535
result = await database.fetch_all(query)
3636

0 commit comments

Comments
 (0)