add getting company
parent
361378929f
commit
0e2ecd3449
|
@ -7,6 +7,8 @@ from api.application.protocols.jwt import JwtTokenProcessor
|
||||||
from api.application.protocols.password_hasher import PasswordHasher
|
from api.application.protocols.password_hasher import PasswordHasher
|
||||||
from api.application.usecase.auth.auth_user import LoginUser
|
from api.application.usecase.auth.auth_user import LoginUser
|
||||||
from api.application.usecase.auth.create_user import CreateUser
|
from api.application.usecase.auth.create_user import CreateUser
|
||||||
|
from api.application.usecase.company.get_users_company import GetCompaniesByOwnerEmail
|
||||||
|
from api.domain.company.repository import CompanyRepository
|
||||||
from api.domain.user.repository import UserRepository
|
from api.domain.user.repository import UserRepository
|
||||||
from api.infrastructure.auth.jwt_settings import JwtSettings
|
from api.infrastructure.auth.jwt_settings import JwtSettings
|
||||||
from api.infrastructure.dependencies.adapters import (
|
from api.infrastructure.dependencies.adapters import (
|
||||||
|
@ -26,8 +28,14 @@ from api.infrastructure.dependencies.protocols import (
|
||||||
get_password_hasher,
|
get_password_hasher,
|
||||||
get_user_login,
|
get_user_login,
|
||||||
)
|
)
|
||||||
from api.infrastructure.dependencies.repositories import get_user_repository
|
from api.infrastructure.dependencies.repositories import (
|
||||||
from api.infrastructure.dependencies.usecases import provide_create_user
|
get_company_repository,
|
||||||
|
get_user_repository,
|
||||||
|
)
|
||||||
|
from api.infrastructure.dependencies.usecases import (
|
||||||
|
provide_create_user,
|
||||||
|
provide_get_companies_by_email,
|
||||||
|
)
|
||||||
from api.infrastructure.persistence.db_setings import DBSettings
|
from api.infrastructure.persistence.db_setings import DBSettings
|
||||||
from api.infrastructure.settings import Settings
|
from api.infrastructure.settings import Settings
|
||||||
|
|
||||||
|
@ -50,5 +58,7 @@ def init_dependencies(app: FastAPI) -> None:
|
||||||
app.dependency_overrides[LoginUser] = get_user_login
|
app.dependency_overrides[LoginUser] = get_user_login
|
||||||
|
|
||||||
app.dependency_overrides[UserRepository] = get_user_repository
|
app.dependency_overrides[UserRepository] = get_user_repository
|
||||||
|
app.dependency_overrides[CompanyRepository] = get_company_repository
|
||||||
|
|
||||||
app.dependency_overrides[CreateUser] = provide_create_user
|
app.dependency_overrides[CreateUser] = provide_create_user
|
||||||
|
app.dependency_overrides[GetCompaniesByOwnerEmail] = provide_get_companies_by_email
|
|
@ -4,8 +4,8 @@ from contextlib import asynccontextmanager
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from sqlalchemy.ext.asyncio import AsyncEngine
|
from sqlalchemy.ext.asyncio import AsyncEngine
|
||||||
|
|
||||||
from api.app_builder.dependencies import init_dependencies
|
from api.app_entrypoint.dependencies import init_dependencies
|
||||||
from api.app_builder.error_handlers import init_exc_handlers
|
from api.app_entrypoint.error_handlers import init_exc_handlers
|
||||||
from api.infrastructure.auth.jwt_settings import JwtSettings
|
from api.infrastructure.auth.jwt_settings import JwtSettings
|
||||||
from api.infrastructure.dependencies.adapters import create_engine
|
from api.infrastructure.dependencies.adapters import create_engine
|
||||||
from api.infrastructure.dependencies.configs import (
|
from api.infrastructure.dependencies.configs import (
|
|
@ -1,13 +1,13 @@
|
||||||
from typing import Protocol
|
from typing import Protocol
|
||||||
|
|
||||||
from api.domain.user.model import UserId
|
from api.domain.user.model import UserEmail, UserId
|
||||||
|
|
||||||
|
|
||||||
class JwtTokenProcessor(Protocol):
|
class JwtTokenProcessor(Protocol):
|
||||||
def generate_token(self, user_id: UserId) -> str:
|
def generate_token(self, user_id: UserId, user_email: UserEmail) -> str:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def validate_token(self, token: str) -> UserId | None:
|
def validate_token(self, token: str) -> tuple[UserId, UserEmail] | None:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def refresh_token(self, token: str) -> str:
|
def refresh_token(self, token: str) -> str:
|
||||||
|
|
|
@ -4,7 +4,6 @@ from uuid import UUID, uuid4
|
||||||
|
|
||||||
from api.domain import DomainValidationError
|
from api.domain import DomainValidationError
|
||||||
from api.domain.entity import DomainEntity
|
from api.domain.entity import DomainEntity
|
||||||
from api.domain.user.model import User
|
|
||||||
from api.domain.value_obj import DomainValueObject
|
from api.domain.value_obj import DomainValueObject
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,13 +40,11 @@ class CompanyId(DomainValueObject):
|
||||||
class Company(DomainEntity[CompanyId]):
|
class Company(DomainEntity[CompanyId]):
|
||||||
name: CompanyName
|
name: CompanyName
|
||||||
email: CompanyEmail
|
email: CompanyEmail
|
||||||
owner: User
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(name: str, email: str, owner: User) -> "Company":
|
def create(name: str, email: str) -> "Company":
|
||||||
return Company(
|
return Company(
|
||||||
id=CompanyId(uuid4()),
|
id=CompanyId(uuid4()),
|
||||||
name=CompanyName(name),
|
name=CompanyName(name),
|
||||||
email=CompanyEmail(email),
|
email=CompanyEmail(email),
|
||||||
owner=owner,
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
from typing import Protocol
|
from typing import Protocol
|
||||||
|
|
||||||
from api.domain.company.model import Company
|
from api.domain.company.model import Company
|
||||||
from api.domain.user.model import User
|
|
||||||
|
|
||||||
|
|
||||||
class CompanyRepository(Protocol):
|
class CompanyRepository(Protocol):
|
||||||
async def get_companies_by_owner_email(self, filter: dict) -> list[Company]:
|
async def get_companies_by_owner_email(self, filter: dict) -> list[Company]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
async def create_company(self, company: Company) -> None:
|
# async def create_company(self, company: Company) -> None:
|
||||||
raise NotImplementedError
|
# raise NotImplementedError
|
||||||
|
#
|
||||||
async def get_workes_list(self) -> list[User]:
|
# async def get_workes_list(self) -> list[User]:
|
||||||
raise NotImplementedError
|
# raise NotImplementedError
|
||||||
|
|
|
@ -7,7 +7,7 @@ from jose.jwt import decode, encode
|
||||||
from api.application.protocols.date_time import DateTimeProvider
|
from api.application.protocols.date_time import DateTimeProvider
|
||||||
from api.application.protocols.jwt import JwtTokenProcessor
|
from api.application.protocols.jwt import JwtTokenProcessor
|
||||||
from api.domain.user.error import UserInvalidCredentialsError
|
from api.domain.user.error import UserInvalidCredentialsError
|
||||||
from api.domain.user.model import UserId
|
from api.domain.user.model import UserEmail, UserId
|
||||||
from api.infrastructure.auth.jwt_settings import JwtSettings
|
from api.infrastructure.auth.jwt_settings import JwtSettings
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class JoseJwtTokenProcessor(JwtTokenProcessor):
|
||||||
self.jwt_options = jwt_options
|
self.jwt_options = jwt_options
|
||||||
self.date_time_provider = date_time_provider
|
self.date_time_provider = date_time_provider
|
||||||
|
|
||||||
def generate_token(self, user_id: UserId) -> str:
|
def generate_token(self, user_id: UserId, user_email: UserEmail) -> str:
|
||||||
issued_at = self.date_time_provider.get_current_time()
|
issued_at = self.date_time_provider.get_current_time()
|
||||||
expiration_time = issued_at + timedelta(minutes=self.jwt_options.expires_in)
|
expiration_time = issued_at + timedelta(minutes=self.jwt_options.expires_in)
|
||||||
|
|
||||||
|
@ -24,19 +24,20 @@ class JoseJwtTokenProcessor(JwtTokenProcessor):
|
||||||
"iat": issued_at,
|
"iat": issued_at,
|
||||||
"exp": expiration_time,
|
"exp": expiration_time,
|
||||||
"sub": str(user_id.value),
|
"sub": str(user_id.value),
|
||||||
|
"email": user_email.value,
|
||||||
}
|
}
|
||||||
|
|
||||||
return encode(claims, self.jwt_options.secret, self.jwt_options.algorithm)
|
return encode(claims, self.jwt_options.secret, self.jwt_options.algorithm)
|
||||||
|
|
||||||
def validate_token(self, token: str) -> UserId | None:
|
def validate_token(self, token: str) -> tuple[UserId, UserEmail] | None:
|
||||||
try:
|
try:
|
||||||
payload = decode(token, self.jwt_options.secret, [self.jwt_options.algorithm])
|
payload = decode(token, self.jwt_options.secret, [self.jwt_options.algorithm])
|
||||||
return UserId(UUID(payload["sub"]))
|
return UserId(UUID(payload["sub"])), UserEmail(payload["email"])
|
||||||
except (JWTError, ValueError, KeyError):
|
except (JWTError, ValueError, KeyError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def refresh_token(self, token: str) -> str:
|
def refresh_token(self, token: str) -> str:
|
||||||
user = self.validate_token(token)
|
token_data = self.validate_token(token)
|
||||||
if user is None:
|
if token_data is None:
|
||||||
raise UserInvalidCredentialsError("invalid token")
|
raise UserInvalidCredentialsError("invalid token")
|
||||||
return self.generate_token(user)
|
return self.generate_token(token_data[0], token_data[1])
|
||||||
|
|
|
@ -3,7 +3,11 @@ from typing import Annotated
|
||||||
from fastapi import Depends
|
from fastapi import Depends
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from api.domain.company.repository import CompanyRepository
|
||||||
from api.domain.user import UserRepository
|
from api.domain.user import UserRepository
|
||||||
|
from api.infrastructure.persistence.repositories.company_repository import (
|
||||||
|
SqlAlchemyCompanyRepository,
|
||||||
|
)
|
||||||
from api.infrastructure.persistence.repositories.user_repository import (
|
from api.infrastructure.persistence.repositories.user_repository import (
|
||||||
SqlAlchemyUserRepository,
|
SqlAlchemyUserRepository,
|
||||||
)
|
)
|
||||||
|
@ -15,3 +19,9 @@ def get_user_repository(
|
||||||
session: Annotated[AsyncSession, Depends(Stub(AsyncSession))],
|
session: Annotated[AsyncSession, Depends(Stub(AsyncSession))],
|
||||||
) -> UserRepository:
|
) -> UserRepository:
|
||||||
return SqlAlchemyUserRepository(session)
|
return SqlAlchemyUserRepository(session)
|
||||||
|
|
||||||
|
|
||||||
|
def get_company_repository(
|
||||||
|
session: Annotated[AsyncSession, Depends(Stub(AsyncSession))],
|
||||||
|
) -> CompanyRepository:
|
||||||
|
return SqlAlchemyCompanyRepository(session)
|
||||||
|
|
|
@ -5,6 +5,8 @@ from fastapi import Depends
|
||||||
from api.application.abstractions.uow import UnitOfWork
|
from api.application.abstractions.uow import UnitOfWork
|
||||||
from api.application.protocols.password_hasher import PasswordHasher
|
from api.application.protocols.password_hasher import PasswordHasher
|
||||||
from api.application.usecase.auth.create_user import CreateUser
|
from api.application.usecase.auth.create_user import CreateUser
|
||||||
|
from api.application.usecase.company.get_users_company import GetCompaniesByOwnerEmail
|
||||||
|
from api.domain.company.repository import CompanyRepository
|
||||||
from api.domain.user.repository import UserRepository
|
from api.domain.user.repository import UserRepository
|
||||||
from api.infrastructure.dependencies.stub import Stub
|
from api.infrastructure.dependencies.stub import Stub
|
||||||
|
|
||||||
|
@ -15,3 +17,9 @@ def provide_create_user(
|
||||||
password_hasher: Annotated[PasswordHasher, Depends(Stub(PasswordHasher))],
|
password_hasher: Annotated[PasswordHasher, Depends(Stub(PasswordHasher))],
|
||||||
) -> CreateUser:
|
) -> CreateUser:
|
||||||
return CreateUser(uow=uow, user_repository=user_repository, password_hasher=password_hasher)
|
return CreateUser(uow=uow, user_repository=user_repository, password_hasher=password_hasher)
|
||||||
|
|
||||||
|
|
||||||
|
def provide_get_companies_by_email(
|
||||||
|
company_repository: Annotated[CompanyRepository, Depends(Stub(CompanyRepository))],
|
||||||
|
) -> GetCompaniesByOwnerEmail:
|
||||||
|
return GetCompaniesByOwnerEmail(company_repository=company_repository)
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
from .base import Base
|
from .base import Base
|
||||||
|
from .company import CompanyModel
|
||||||
from .user import UserModel
|
from .user import UserModel
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"Base",
|
"Base",
|
||||||
"UserModel",
|
"UserModel",
|
||||||
|
"CompanyModel",
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
from sqlalchemy import UUID
|
||||||
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
|
||||||
|
from api.infrastructure.persistence.models.base import Base
|
||||||
|
|
||||||
|
|
||||||
|
class CompanyModel(Base):
|
||||||
|
__tablename__ = "companies"
|
||||||
|
|
||||||
|
id: Mapped[uuid.UUID] = mapped_column(
|
||||||
|
UUID(as_uuid=True),
|
||||||
|
primary_key=True,
|
||||||
|
)
|
||||||
|
name: Mapped[str]
|
||||||
|
email: Mapped[str] = mapped_column(unique=True)
|
|
@ -1,45 +1,45 @@
|
||||||
# from sqlalchemy import text
|
from sqlalchemy import text
|
||||||
# from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
#
|
|
||||||
# from api.domain.company import CompanyRepository, company
|
from api.domain.company.model import Company, CompanyEmail, CompanyId, CompanyName
|
||||||
# from api.domain.user.model import UserEmail, UserFirstName, UserId
|
from api.domain.company.repository import CompanyRepository
|
||||||
#
|
|
||||||
#
|
|
||||||
# class SqlAlchemyUserRepository(UserRepository):
|
class SqlAlchemyCompanyRepository(CompanyRepository):
|
||||||
# def __init__(self, session: AsyncSession) -> None:
|
def __init__(self, session: AsyncSession) -> None:
|
||||||
# self.session = session
|
self.session = session
|
||||||
#
|
|
||||||
# async def create_user(self, user: User) -> None:
|
# async def create_user(self, user: User) -> None:
|
||||||
# stmt = text(
|
# stmt = text(
|
||||||
# """INSERT INTO users (id, name, email, hashed_password)
|
# """INSERT INTO users (id, name, email, hashed_password)
|
||||||
# VALUES(:id, :name, :email, :hashed_password)
|
# VALUES(:id, :name, :email, :hashed_password)
|
||||||
# """
|
# """
|
||||||
# )
|
# )
|
||||||
# await self.session.execute(
|
# await self.session.execute(
|
||||||
# stmt,
|
# stmt,
|
||||||
# {
|
# {
|
||||||
# "id": str(user.id.value),
|
# "id": str(user.id.value),
|
||||||
# "name": user.name.value,
|
# "name": user.name.value,
|
||||||
# "email": user.email.value,
|
# "email": user.email.value,
|
||||||
# "hashed_password": user.hashed_password,
|
# "hashed_password": user.hashed_password,
|
||||||
# },
|
# },
|
||||||
# )
|
# )
|
||||||
#
|
#
|
||||||
# async def get_user(self, filter: dict) -> User | None:
|
async def get_companies_by_owner_email(self, filter: dict) -> list[Company]:
|
||||||
# stmt = text("""SELECT * FROM users WHERE email = :val""")
|
stmt = text("""SELECT * FROM companies WHERE email = :val""")
|
||||||
# result = await self.session.execute(stmt, {"val": filter["email"]})
|
result = await self.session.execute(stmt, {"val": filter["email"]})
|
||||||
#
|
|
||||||
# result = result.mappings().one_or_none()
|
result = result.mappings().all()
|
||||||
#
|
|
||||||
# if result is None:
|
return [
|
||||||
# return None
|
Company(
|
||||||
#
|
id=CompanyId(c.id),
|
||||||
# return User(
|
name=CompanyName(c.name),
|
||||||
# id=UserId(result.id),
|
email=CompanyEmail(c.email),
|
||||||
# name=UserFirstName(result.name),
|
)
|
||||||
# email=UserEmail(result.email),
|
for c in result
|
||||||
# hashed_password=result.hashed_password,
|
]
|
||||||
# )
|
|
||||||
#
|
|
||||||
# async def get_users(self) -> list[User]:
|
# async def get_users(self) -> list[User]:
|
||||||
# return []
|
# return []
|
||||||
|
|
|
@ -8,7 +8,7 @@ from api.application.contracts.auth.auth_response import AuthenticationResponse
|
||||||
from api.application.protocols.jwt import JwtTokenProcessor
|
from api.application.protocols.jwt import JwtTokenProcessor
|
||||||
from api.application.usecase.auth.auth_user import LoginUser
|
from api.application.usecase.auth.auth_user import LoginUser
|
||||||
from api.application.usecase.auth.create_user import CreateUser
|
from api.application.usecase.auth.create_user import CreateUser
|
||||||
from api.domain.user.model import UserId
|
from api.domain.user.model import UserEmail, UserId
|
||||||
from api.infrastructure.dependencies.stub import Stub
|
from api.infrastructure.dependencies.stub import Stub
|
||||||
|
|
||||||
auth_router = APIRouter(prefix="/auth", tags=["Auth"])
|
auth_router = APIRouter(prefix="/auth", tags=["Auth"])
|
||||||
|
@ -35,7 +35,7 @@ async def login(
|
||||||
password=login_request.password,
|
password=login_request.password,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
token = token_processor.generate_token(UserId(user.id))
|
token = token_processor.generate_token(UserId(user.id), UserEmail(user.email))
|
||||||
response.set_cookie(key="access_token", value=f"Bearer {token}", httponly=True)
|
response.set_cookie(key="access_token", value=f"Bearer {token}", httponly=True)
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, Request
|
from fastapi import APIRouter, Depends, Request
|
||||||
|
|
||||||
|
from api.application.contracts.company.company_request import CompanyByOwnerEmail
|
||||||
from api.application.contracts.company.company_response import CompanyBaseResponse
|
from api.application.contracts.company.company_response import CompanyBaseResponse
|
||||||
|
from api.application.protocols.jwt import JwtTokenProcessor
|
||||||
|
from api.application.usecase.company.get_users_company import GetCompaniesByOwnerEmail
|
||||||
|
from api.domain.user.error import UserValidationError
|
||||||
|
from api.infrastructure.dependencies.stub import Stub
|
||||||
from api.presentation.auth.fasapi_auth import auth_required
|
from api.presentation.auth.fasapi_auth import auth_required
|
||||||
|
|
||||||
company_router = APIRouter(prefix="/company", tags=["Company"])
|
company_router = APIRouter(prefix="/company", tags=["Company"])
|
||||||
|
@ -11,8 +18,19 @@ company_router = APIRouter(prefix="/company", tags=["Company"])
|
||||||
response_model=None,
|
response_model=None,
|
||||||
dependencies=[Depends(auth_required)],
|
dependencies=[Depends(auth_required)],
|
||||||
)
|
)
|
||||||
async def get_company(request: Request) -> CompanyBaseResponse:
|
async def get_companies(
|
||||||
return CompanyBaseResponse(
|
request: Request,
|
||||||
name="some",
|
token_processor: Annotated[JwtTokenProcessor, Depends(Stub(JwtTokenProcessor))],
|
||||||
email="some",
|
usecase: Annotated[GetCompaniesByOwnerEmail, Depends(Stub(GetCompaniesByOwnerEmail))],
|
||||||
)
|
) -> list[CompanyBaseResponse]:
|
||||||
|
token_data = token_processor.validate_token(request.scope["auth"])
|
||||||
|
if not token_data:
|
||||||
|
raise UserValidationError("Login required")
|
||||||
|
companies = await usecase.execute(request=CompanyByOwnerEmail(email=token_data[1].value))
|
||||||
|
return [
|
||||||
|
CompanyBaseResponse(
|
||||||
|
name=c.name,
|
||||||
|
email=c.email,
|
||||||
|
)
|
||||||
|
for c in companies
|
||||||
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
db:
|
db:
|
||||||
host: "localhost"
|
host: "db"
|
||||||
port: 5432
|
port: 5432
|
||||||
database: "serviceman_db"
|
database: "serviceman_db"
|
||||||
user: "demo_user"
|
user: "demo_user"
|
||||||
|
|
|
@ -44,7 +44,7 @@ services:
|
||||||
- ./api:/usr/src/service_man/api
|
- ./api:/usr/src/service_man/api
|
||||||
# - ./alembic.ini:/usr/src/service_man/alembic.ini
|
# - ./alembic.ini:/usr/src/service_man/alembic.ini
|
||||||
|
|
||||||
command: /bin/bash -c 'cd /usr/src/service_man && poetry run uvicorn api.app_builder.main:app_factory --host 0.0.0.0 --reload --factory'
|
command: /bin/bash -c 'poetry run uvicorn api.app_entrypoint.main:app_factory --host 0.0.0.0 --reload --factory'
|
||||||
|
|
||||||
# bot:
|
# bot:
|
||||||
# container_name: bot
|
# container_name: bot
|
||||||
|
|
|
@ -2,7 +2,7 @@ if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
uvicorn.run(
|
uvicorn.run(
|
||||||
app="api.app_builder.main:app_factory",
|
app="api.app_entrypoint.main:app_factory",
|
||||||
host="0.0.0.0",
|
host="0.0.0.0",
|
||||||
port=8000,
|
port=8000,
|
||||||
reload=True,
|
reload=True,
|
||||||
|
|
|
@ -1196,7 +1196,6 @@ files = [
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
|
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
||||||
|
@ -1565,4 +1564,4 @@ multidict = ">=4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.10"
|
python-versions = "^3.10"
|
||||||
content-hash = "586dbb5fd80f9999d39a1cb960a06bc8f15e3b103f1c273e4d954fca0b1ffc75"
|
content-hash = "e718faa94188a6831502fbe2b89da05cc97f959502b671761995673aa0f018b8"
|
||||||
|
|
|
@ -7,10 +7,6 @@ readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = "^3.10"
|
python = "^3.10"
|
||||||
python-jose = "^3.3.0"
|
|
||||||
python-multipart = "^0.0.9"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
pre-commit = "^3.6.2"
|
pre-commit = "^3.6.2"
|
||||||
|
@ -27,6 +23,8 @@ uvicorn = "^0.27.1"
|
||||||
pyyaml = "^6.0.1"
|
pyyaml = "^6.0.1"
|
||||||
alembic = "^1.13.1"
|
alembic = "^1.13.1"
|
||||||
passlib = "^1.7.4"
|
passlib = "^1.7.4"
|
||||||
|
python-jose = "^3.3.0"
|
||||||
|
python-multipart = "^0.0.9"
|
||||||
|
|
||||||
[tool.poetry.group.bot.dependencies]
|
[tool.poetry.group.bot.dependencies]
|
||||||
aiogram = "^3.4.1"
|
aiogram = "^3.4.1"
|
||||||
|
|
Loading…
Reference in New Issue