diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml index 4e31eb2..f43ef1a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,3 +30,64 @@ dependencies = [ [build-system] requires = ["poetry-core>=2.0.0,<3.0.0"] build-backend = "poetry.core.masonry.api" + +[tool.ruff] +# Exclude commonly ignored directories and files. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".ipynb_checkpoints", + ".mypy_cache", + ".nox", + ".pants.d", + ".pyenv", + ".pytest_cache", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + ".vscode", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "site-packages", + "venv", +] +# Set the maximum line length for both linting and formatting. +line-length = 88 +# Assume Python 3.9 for compatibility checks. +target-version = "py39" +# Enable preview features for early access to new rules and formatting changes. +preview = true + +[tool.ruff.lint] +# Select specific rule groups to enable. +# 'E' for pycodestyle, 'F' for Pyflakes, 'I' for isort, 'B' for flake8-bugbear. +select = [ + "E", + "F", + "I", + "B", + "UP", # pyupgrade + "SIM", # flake8-simplify +] +# Ignore specific rules within the selected groups. +ignore = [ + "UP035", + "B903", + "B904", + "E501", + "B008", +] + +[tool.ruff.format] +# Enable Ruff's formatter. +docstring-code-format = true \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/api/dependacies/user_dep.py b/src/api/dependacies/user_dep.py index 36cd0e4..d8597fa 100644 --- a/src/api/dependacies/user_dep.py +++ b/src/api/dependacies/user_dep.py @@ -1,14 +1,14 @@ from typing import Annotated -from fastapi import HTTPException, Depends, Path +from fastapi import Depends, HTTPException, Path from fastapi.security import OAuth2PasswordBearer from jwt import InvalidTokenError +from src.api.dependacies.db_dep import sessionDep from src.core.auth_manager import AuthManager from src.core.settings import settings from src.schemas.auth import TokenData from src.services.users import UserService -from src.api.dependacies.db_dep import sessionDep oauth2_scheme = OAuth2PasswordBearer(tokenUrl=f"{settings.api.v1_login_url}/login") diff --git a/src/api/v1/__init__.py b/src/api/v1/__init__.py index aad979a..7d08ae6 100644 --- a/src/api/v1/__init__.py +++ b/src/api/v1/__init__.py @@ -1,7 +1,8 @@ from fastapi import APIRouter + from src.api.v1.auth import router as auth_router -from src.api.v1.users import router as users_router from src.api.v1.tasks import router as tasks_router +from src.api.v1.users import router as users_router from src.core.settings import settings router = APIRouter(prefix=settings.api.v1.prefix) diff --git a/src/api/v1/auth.py b/src/api/v1/auth.py index 4aa181d..a969cca 100644 --- a/src/api/v1/auth.py +++ b/src/api/v1/auth.py @@ -4,8 +4,8 @@ from fastapi import APIRouter, Depends from fastapi.security import OAuth2PasswordRequestForm from src.api.dependacies.db_dep import sessionDep -from src.schemas.users import UserRequestADD from src.core.settings import settings +from src.schemas.users import UserRequestADD from src.services.auth import AuthService router = APIRouter(prefix=settings.api.v1.auth, tags=["Auth"]) diff --git a/src/api/v1/tasks.py b/src/api/v1/tasks.py index 9a74f2d..35c51dd 100644 --- a/src/api/v1/tasks.py +++ b/src/api/v1/tasks.py @@ -9,7 +9,7 @@ router = APIRouter(prefix="/tasks", tags=["Tasks"]) @router.get("/") -async def get_tasks(db:sessionDep,user: ActiveUser): +async def get_tasks(db: sessionDep, user: ActiveUser): query = select(TasksORM.id, TasksORM.description).where(TasksORM.user_id == user.id) tasks = await db.session.execute(query) result = tasks.scalars().all() diff --git a/src/api/v1/users.py b/src/api/v1/users.py index e00e3f7..05752c3 100644 --- a/src/api/v1/users.py +++ b/src/api/v1/users.py @@ -1,10 +1,9 @@ -from fastapi import APIRouter -from fastapi import Body +from fastapi import APIRouter, Body -from src.schemas.users import UserUpdate -from src.api.dependacies.user_dep import ActiveUser, AdminUser, CurrentOrAdmin from src.api.dependacies.db_dep import sessionDep +from src.api.dependacies.user_dep import ActiveUser, AdminUser, CurrentOrAdmin from src.core.settings import settings +from src.schemas.users import UserUpdate from src.services.users import UserService router = APIRouter(prefix=settings.api.v1.users, tags=["Users"]) diff --git a/src/core/auth_manager.py b/src/core/auth_manager.py index 408b532..ef448f6 100644 --- a/src/core/auth_manager.py +++ b/src/core/auth_manager.py @@ -1,4 +1,4 @@ -from datetime import timedelta, datetime, timezone +from datetime import datetime, timedelta, timezone import jwt from passlib.context import CryptContext diff --git a/src/core/database.py b/src/core/database.py index 87fdd37..98738a4 100644 --- a/src/core/database.py +++ b/src/core/database.py @@ -1,7 +1,7 @@ from datetime import datetime -from sqlalchemy import TIMESTAMP, func, event -from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker +from sqlalchemy import TIMESTAMP, event, func +from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column from src.core.settings import settings diff --git a/src/core/settings.py b/src/core/settings.py index c27c294..79f7f74 100644 --- a/src/core/settings.py +++ b/src/core/settings.py @@ -37,6 +37,7 @@ class AccessToken(BaseSettings): expire_minutes: int = 15 secret_key: str algorithm: str = "HS256" + token_type: str = "bearer" # noqa: S105 class Settings(BaseSettings): diff --git a/src/main.py b/src/main.py index 456377f..300d34e 100644 --- a/src/main.py +++ b/src/main.py @@ -1,8 +1,8 @@ import sys -import uvicorn from pathlib import Path -from fastapi import FastAPI +import uvicorn +from fastapi import FastAPI sys.path.append(str(Path(__file__).parent.parent)) from src.api import router diff --git a/src/migrations/env.py b/src/migrations/env.py index 695e45d..f7b6a35 100644 --- a/src/migrations/env.py +++ b/src/migrations/env.py @@ -1,8 +1,7 @@ from logging.config import fileConfig -from sqlalchemy import engine_from_config, event -from sqlalchemy import pool from alembic import context +from sqlalchemy import engine_from_config, event, pool from src.core.database import Base from src.models import * # noqa diff --git a/src/migrations/versions/2025_07_06_0002-a2fdd0ec4a96_init.py b/src/migrations/versions/2025_07_06_0002-a2fdd0ec4a96_init.py index e62e52e..f1c37c7 100644 --- a/src/migrations/versions/2025_07_06_0002-a2fdd0ec4a96_init.py +++ b/src/migrations/versions/2025_07_06_0002-a2fdd0ec4a96_init.py @@ -8,9 +8,8 @@ Create Date: 2025-07-06 00:02:09.254907 from typing import Sequence, Union -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision: str = "a2fdd0ec4a96" diff --git a/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py b/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py index 032fcdd..195c8e1 100644 --- a/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py +++ b/src/migrations/versions/2025_08_06_2341-197b195208e8_add_cascade_delete_to_tasks.py @@ -8,9 +8,8 @@ Create Date: 2025-08-06 23:41:56.778423 from typing import Sequence, Union -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision: str = "197b195208e8" @@ -36,9 +35,9 @@ def upgrade(): break if constraint_name: - try: + try: # noqa: SIM105 batch_op.drop_constraint(constraint_name, type_="foreignkey") - except: # noqa E722 + except: # noqa E722 pass batch_op.create_foreign_key( @@ -49,9 +48,9 @@ def upgrade(): def downgrade(): """Downgrade schema.""" with op.batch_alter_table("tasks", schema=None) as batch_op: - try: + try: # noqa: SIM105 batch_op.drop_constraint("fk_tasks_user_id_users", type_="foreignkey") - except: # noqa E722 + except: # noqa E722 pass batch_op.create_foreign_key( diff --git a/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py b/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py index 9398bcd..6bb4d15 100644 --- a/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py +++ b/src/migrations/versions/2025_08_06_2354-4b0f3ea2fd26_fix_duplicate_foreign_keys.py @@ -6,11 +6,10 @@ Create Date: 2025-08-06 23:54:24.308488 """ -from typing import Sequence, Union +from typing import Sequence, Union # noqa: UP035 -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision: str = "4b0f3ea2fd26" @@ -31,9 +30,9 @@ def upgrade(): for fk in foreign_keys: if "user_id" in fk["constrained_columns"]: - try: + try: # noqa: SIM105 batch_op.drop_constraint(fk["name"], type_="foreignkey") - except: # noqa E722 + except: # noqa E722 pass batch_op.create_foreign_key( @@ -44,9 +43,9 @@ def upgrade(): def downgrade(): """Downgrade schema.""" with op.batch_alter_table("tasks", schema=None) as batch_op: - try: + try: # noqa: SIM105 batch_op.drop_constraint("fk_tasks_user_id_users", type_="foreignkey") - except: # noqa E722 + except: # noqa E722 pass batch_op.create_foreign_key( "fk_tasks_user_id_users", "users", ["user_id"], ["id"] diff --git a/src/models/__init__.py b/src/models/__init__.py index d1a9da9..e4c877d 100644 --- a/src/models/__init__.py +++ b/src/models/__init__.py @@ -1,5 +1,5 @@ -from src.models.users import UsersORM from src.models.tasks import TasksORM +from src.models.users import UsersORM __all__ = [ "UsersORM", diff --git a/src/models/tasks.py b/src/models/tasks.py index fb82743..10bdcde 100644 --- a/src/models/tasks.py +++ b/src/models/tasks.py @@ -1,7 +1,7 @@ from datetime import date -from typing import Optional, TYPE_CHECKING +from typing import TYPE_CHECKING, Optional -from sqlalchemy import ForeignKey, Text, Date, Enum, String +from sqlalchemy import Date, Enum, ForeignKey, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from src.core.database import Base diff --git a/src/models/users.py b/src/models/users.py index 407c29b..80d149d 100644 --- a/src/models/users.py +++ b/src/models/users.py @@ -1,6 +1,6 @@ -from typing import Optional, TYPE_CHECKING +from typing import TYPE_CHECKING, Optional -from sqlalchemy import String, BigInteger, Integer, Boolean +from sqlalchemy import BigInteger, Boolean, Integer, String from sqlalchemy.orm import Mapped, mapped_column, relationship from src.core.database import Base diff --git a/src/repository/tasks.py b/src/repository/tasks.py index 4709aaa..9925ab1 100644 --- a/src/repository/tasks.py +++ b/src/repository/tasks.py @@ -1,5 +1,6 @@ -from src.repository.base import BaseRepo from src.models.tasks import TasksORM +from src.repository.base import BaseRepo + class TasksRepo(BaseRepo): model = TasksORM diff --git a/src/schemas/users.py b/src/schemas/users.py index 454592b..15e3dd6 100644 --- a/src/schemas/users.py +++ b/src/schemas/users.py @@ -1,6 +1,6 @@ from typing import Annotated -from pydantic import BaseModel, EmailStr, ConfigDict, BeforeValidator +from pydantic import BaseModel, BeforeValidator, ConfigDict, EmailStr from src.schemas.validators import ensure_password diff --git a/src/services/auth.py b/src/services/auth.py index 5e805dc..5077ade 100644 --- a/src/services/auth.py +++ b/src/services/auth.py @@ -1,9 +1,10 @@ from fastapi import HTTPException -from src.schemas.auth import Token -from src.schemas.users import UserRequestADD, User, UserAdd, UserWithHashedPass -from src.services.base import BaseService from src.core.auth_manager import AuthManager +from src.core.settings import settings +from src.schemas.auth import Token +from src.schemas.users import User, UserAdd, UserRequestADD, UserWithHashedPass +from src.services.base import BaseService class AuthService(BaseService): @@ -37,4 +38,6 @@ class AuthService(BaseService): access_token = AuthManager.create_access_token( data={"id": user.id, "sub": user.username, "is_active": user.is_active} ) - return Token(access_token=access_token, token_type="bearer") + return Token( + access_token=access_token, token_type=settings.access_token.token_type + ) diff --git a/src/services/tasks.py b/src/services/tasks.py index 5d19bf9..4a7c51d 100644 --- a/src/services/tasks.py +++ b/src/services/tasks.py @@ -1,4 +1,4 @@ -from services.base import BaseService +from src.services.base import BaseService class TasksService(BaseService): ...