add User return schema
This commit is contained in:
@@ -6,4 +6,3 @@ from src.core.settings import settings
|
|||||||
router = APIRouter(prefix=settings.api.prefix)
|
router = APIRouter(prefix=settings.api.prefix)
|
||||||
|
|
||||||
router.include_router(router=v1_router)
|
router.include_router(router=v1_router)
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ from src.schemas.users import UserRequest
|
|||||||
from src.core.settings import settings
|
from src.core.settings import settings
|
||||||
from src.services.auth import AuthService
|
from src.services.auth import AuthService
|
||||||
|
|
||||||
router = APIRouter(prefix=settings.api.v1.auth, tags=['Auth'])
|
router = APIRouter(prefix=settings.api.v1.auth, tags=["Auth"])
|
||||||
|
|
||||||
|
|
||||||
@router.post(path='/signup')
|
@router.post(path="/signup")
|
||||||
async def registration(session: sessionDep, credential: UserRequest):
|
async def registration(session: sessionDep, credential: UserRequest):
|
||||||
await AuthService(session).registration(credential)
|
auth = await AuthService(session).registration(credential)
|
||||||
|
return auth
|
||||||
|
|||||||
@@ -6,11 +6,8 @@ from src.repository.users import UsersRepo
|
|||||||
class IUnitOfWork(Protocol):
|
class IUnitOfWork(Protocol):
|
||||||
user: UsersRepo
|
user: UsersRepo
|
||||||
|
|
||||||
async def __aenter__(self) -> "IUnitOfWork":
|
async def __aenter__(self) -> "IUnitOfWork": ...
|
||||||
...
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None:
|
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: ...
|
||||||
...
|
|
||||||
|
|
||||||
async def commit(self) -> None:
|
async def commit(self) -> None: ...
|
||||||
...
|
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ class DbSettings(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class AccessToken(BaseSettings):
|
class AccessToken(BaseSettings):
|
||||||
model_config = SettingsConfigDict(env_file='.env',
|
model_config = SettingsConfigDict(
|
||||||
env_file_encoding='utf-8',
|
env_file=".env", env_file_encoding="utf-8", env_prefix="ACCESS_TOKEN_"
|
||||||
env_prefix="ACCESS_TOKEN_"
|
)
|
||||||
)
|
|
||||||
expire_minutes: int = 15
|
expire_minutes: int = 15
|
||||||
secret_key: str
|
secret_key: str
|
||||||
algorithm: str = "HS256"
|
algorithm: str = "HS256"
|
||||||
@@ -40,4 +39,4 @@ class Settings(BaseSettings):
|
|||||||
|
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
print(settings.db.url)
|
print(settings.db.url)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from sqlalchemy import pool
|
|||||||
from alembic import context
|
from alembic import context
|
||||||
|
|
||||||
from src.db.database import Base
|
from src.db.database import Base
|
||||||
from src.models import * # noqa
|
from src.models import * # noqa
|
||||||
|
|
||||||
# this is the Alembic Config object, which provides
|
# this is the Alembic Config object, which provides
|
||||||
# access to the values within the .ini file in use.
|
# access to the values within the .ini file in use.
|
||||||
@@ -68,9 +68,7 @@ def run_migrations_online() -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
with connectable.connect() as connection:
|
with connectable.connect() as connection:
|
||||||
context.configure(
|
context.configure(connection=connection, target_metadata=target_metadata)
|
||||||
connection=connection, target_metadata=target_metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
context.run_migrations()
|
context.run_migrations()
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
"""init
|
"""init
|
||||||
|
|
||||||
Revision ID: a2fdd0ec4a96
|
Revision ID: a2fdd0ec4a96
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2025-07-06 00:02:09.254907
|
Create Date: 2025-07-06 00:02:09.254907
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Sequence, Union
|
from typing import Sequence, Union
|
||||||
|
|
||||||
from alembic import op
|
from alembic import op
|
||||||
@@ -12,7 +13,7 @@ import sqlalchemy as sa
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision: str = 'a2fdd0ec4a96'
|
revision: str = "a2fdd0ec4a96"
|
||||||
down_revision: Union[str, None] = None
|
down_revision: Union[str, None] = None
|
||||||
branch_labels: Union[str, Sequence[str], None] = None
|
branch_labels: Union[str, Sequence[str], None] = None
|
||||||
depends_on: Union[str, Sequence[str], None] = None
|
depends_on: Union[str, Sequence[str], None] = None
|
||||||
@@ -21,34 +22,61 @@ depends_on: Union[str, Sequence[str], None] = None
|
|||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
"""Upgrade schema."""
|
"""Upgrade schema."""
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('users',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"users",
|
||||||
sa.Column('username', sa.String(length=30), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('hashed_password', sa.String(length=255), nullable=False),
|
sa.Column("username", sa.String(length=30), nullable=False),
|
||||||
sa.Column('email', sa.String(length=255), nullable=True),
|
sa.Column("hashed_password", sa.String(length=255), nullable=False),
|
||||||
sa.Column('telegram_id', sa.BigInteger(), nullable=True),
|
sa.Column("email", sa.String(length=255), nullable=True),
|
||||||
sa.Column('avatar_path', sa.String(length=255), nullable=True),
|
sa.Column("telegram_id", sa.BigInteger(), nullable=True),
|
||||||
sa.Column('is_active', sa.Boolean(), nullable=False),
|
sa.Column("avatar_path", sa.String(length=255), nullable=True),
|
||||||
sa.Column('is_superuser', sa.Boolean(), nullable=False),
|
sa.Column("is_active", sa.Boolean(), nullable=False),
|
||||||
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
sa.Column("is_superuser", sa.Boolean(), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column(
|
||||||
sa.UniqueConstraint('email')
|
"created_at",
|
||||||
|
sa.TIMESTAMP(timezone=True),
|
||||||
|
server_default=sa.text("(CURRENT_TIMESTAMP)"),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("email"),
|
||||||
)
|
)
|
||||||
op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True)
|
op.create_index(op.f("ix_users_username"), "users", ["username"], unique=True)
|
||||||
op.create_table('tasks',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
"tasks",
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
|
||||||
sa.Column('title', sa.String(length=100), nullable=False),
|
sa.Column("user_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('description', sa.Text(), nullable=True),
|
sa.Column("title", sa.String(length=100), nullable=False),
|
||||||
sa.Column('due_date', sa.Date(), nullable=True),
|
sa.Column("description", sa.Text(), nullable=True),
|
||||||
sa.Column("status", sa.Enum("open", "closed", "in_progress", "todo", name="status_enum"), nullable=False),
|
sa.Column("due_date", sa.Date(), nullable=True),
|
||||||
sa.CheckConstraint("status IN ('open', 'closed', 'in_progress', 'todo')", name="ck_status_enum"),
|
sa.Column(
|
||||||
sa.Column("priority", sa.Enum("low", "medium", "high", "critical", name="priority_enum"), nullable=False),
|
"status",
|
||||||
sa.CheckConstraint("priority in ('low', 'medium', 'high', 'critical')", name="ck_priority_enum"),
|
sa.Enum("open", "closed", "in_progress", "todo", name="status_enum"),
|
||||||
sa.Column('time_spent', sa.Integer(), nullable=False),
|
nullable=False,
|
||||||
sa.Column('created_at', sa.TIMESTAMP(timezone=True), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
|
),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
|
sa.CheckConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
"status IN ('open', 'closed', 'in_progress', 'todo')", name="ck_status_enum"
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"priority",
|
||||||
|
sa.Enum("low", "medium", "high", "critical", name="priority_enum"),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"priority in ('low', 'medium', 'high', 'critical')", name="ck_priority_enum"
|
||||||
|
),
|
||||||
|
sa.Column("time_spent", sa.Integer(), nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"created_at",
|
||||||
|
sa.TIMESTAMP(timezone=True),
|
||||||
|
server_default=sa.text("(CURRENT_TIMESTAMP)"),
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user_id"],
|
||||||
|
["users.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
@@ -56,7 +84,7 @@ def upgrade() -> None:
|
|||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
"""Downgrade schema."""
|
"""Downgrade schema."""
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('tasks')
|
op.drop_table("tasks")
|
||||||
op.drop_index(op.f('ix_users_username'), table_name='users')
|
op.drop_index(op.f("ix_users_username"), table_name="users")
|
||||||
op.drop_table('users')
|
op.drop_table("users")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ priority_enum = Enum("low", "medium", "high", "critical", name="priority_enum")
|
|||||||
|
|
||||||
|
|
||||||
class TasksORM(Base):
|
class TasksORM(Base):
|
||||||
|
|
||||||
__tablename__ = "tasks"
|
__tablename__ = "tasks"
|
||||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||||
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ class UsersORM(Base):
|
|||||||
String(30), nullable=False, unique=True, index=True
|
String(30), nullable=False, unique=True, index=True
|
||||||
)
|
)
|
||||||
hashed_password: Mapped[str] = mapped_column(String(255), nullable=False)
|
hashed_password: Mapped[str] = mapped_column(String(255), nullable=False)
|
||||||
email: Mapped[Optional[str]] = mapped_column(String(255), unique=True, nullable=True)
|
email: Mapped[Optional[str]] = mapped_column(
|
||||||
|
String(255), unique=True, nullable=True
|
||||||
|
)
|
||||||
telegram_id: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True)
|
telegram_id: Mapped[Optional[int]] = mapped_column(BigInteger, nullable=True)
|
||||||
avatar_path: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
avatar_path: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
|
||||||
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class BaseRepo:
|
|||||||
self.session = session
|
self.session = session
|
||||||
|
|
||||||
async def create_one(self, data: BaseModel):
|
async def create_one(self, data: BaseModel):
|
||||||
print(self.session)
|
|
||||||
statement = insert(self.model).values(data.model_dump()).returning(self.model)
|
statement = insert(self.model).values(data.model_dump()).returning(self.model)
|
||||||
result = await self.session.execute(statement)
|
result = await self.session.execute(statement)
|
||||||
return result
|
obj = result.scalar_one()
|
||||||
|
return obj
|
||||||
|
|||||||
@@ -6,11 +6,12 @@ from src.schemas.validators import ensure_password
|
|||||||
|
|
||||||
|
|
||||||
class User(BaseModel):
|
class User(BaseModel):
|
||||||
|
id: int
|
||||||
email: EmailStr | None
|
email: EmailStr | None
|
||||||
username: str
|
username: str
|
||||||
is_active: bool
|
is_active: bool
|
||||||
is_superuser: bool
|
is_superuser: bool
|
||||||
model_config = ConfigDict(from_attributes=True)
|
model_config = ConfigDict(from_attributes=True, extra="ignore")
|
||||||
|
|
||||||
|
|
||||||
class UserWithHashedPass(User):
|
class UserWithHashedPass(User):
|
||||||
@@ -21,3 +22,11 @@ class UserRequest(BaseModel):
|
|||||||
username: str
|
username: str
|
||||||
email: EmailStr | None = None
|
email: EmailStr | None = None
|
||||||
password: Annotated[str, BeforeValidator(ensure_password)]
|
password: Annotated[str, BeforeValidator(ensure_password)]
|
||||||
|
|
||||||
|
|
||||||
|
class UserAdd(BaseModel):
|
||||||
|
email: EmailStr | None
|
||||||
|
username: str
|
||||||
|
is_active: bool
|
||||||
|
is_superuser: bool
|
||||||
|
hashed_password: str
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
from src.schemas.users import UserWithHashedPass, UserRequest
|
from src.schemas.users import UserRequest, User, UserAdd
|
||||||
from src.services.base import BaseService
|
from src.services.base import BaseService
|
||||||
from src.utils.auth_manager import AuthManger
|
from src.utils.auth_manager import AuthManger
|
||||||
|
|
||||||
|
|
||||||
class AuthService(BaseService):
|
class AuthService(BaseService):
|
||||||
|
async def registration(self, cred: UserRequest) -> User:
|
||||||
async def registration(self, cred: UserRequest):
|
|
||||||
hashed_pass = AuthManger.get_password_hash(cred.password)
|
hashed_pass = AuthManger.get_password_hash(cred.password)
|
||||||
user_to_insert = UserWithHashedPass(
|
user_to_insert = UserAdd(
|
||||||
username=cred.username,
|
username=cred.username,
|
||||||
email=cred.email,
|
email=cred.email,
|
||||||
hashed_password=hashed_pass,
|
hashed_password=hashed_pass,
|
||||||
is_active=True,
|
is_active=True,
|
||||||
is_superuser=False
|
is_superuser=False,
|
||||||
)
|
)
|
||||||
result = await self.session.user.create_one(user_to_insert)
|
result = await self.session.user.create_one(user_to_insert)
|
||||||
|
print(result)
|
||||||
await self.session.commit()
|
await self.session.commit()
|
||||||
return result
|
return User.model_validate(result)
|
||||||
|
|||||||
@@ -23,7 +23,13 @@ class AuthManger:
|
|||||||
if expires_delta:
|
if expires_delta:
|
||||||
expire = datetime.now(timezone.utc) + expires_delta
|
expire = datetime.now(timezone.utc) + expires_delta
|
||||||
else:
|
else:
|
||||||
expire = datetime.now(timezone.utc) + timedelta(minutes=settings.access_token.expire_minutes)
|
expire = datetime.now(timezone.utc) + timedelta(
|
||||||
|
minutes=settings.access_token.expire_minutes
|
||||||
|
)
|
||||||
to_encode.update({"exp": expire})
|
to_encode.update({"exp": expire})
|
||||||
encoded_jwt = jwt.encode(to_encode, settings.access_token.secret_key, algorithm=settings.access_token.algorithm)
|
encoded_jwt = jwt.encode(
|
||||||
|
to_encode,
|
||||||
|
settings.access_token.secret_key,
|
||||||
|
algorithm=settings.access_token.algorithm,
|
||||||
|
)
|
||||||
return encoded_jwt
|
return encoded_jwt
|
||||||
|
|||||||
Reference in New Issue
Block a user