base logic
This commit is contained in:
39
poetry.lock
generated
39
poetry.lock
generated
@@ -101,6 +101,43 @@ files = [
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dnspython"
|
||||
version = "2.7.0"
|
||||
description = "DNS toolkit"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"},
|
||||
{file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=23.1.0)", "coverage (>=7.0)", "flake8 (>=7)", "hypercorn (>=0.16.0)", "mypy (>=1.8)", "pylint (>=3)", "pytest (>=7.4)", "pytest-cov (>=4.1.0)", "quart-trio (>=0.11.0)", "sphinx (>=7.2.0)", "sphinx-rtd-theme (>=2.0.0)", "twine (>=4.0.0)", "wheel (>=0.42.0)"]
|
||||
dnssec = ["cryptography (>=43)"]
|
||||
doh = ["h2 (>=4.1.0)", "httpcore (>=1.0.0)", "httpx (>=0.26.0)"]
|
||||
doq = ["aioquic (>=1.0.0)"]
|
||||
idna = ["idna (>=3.7)"]
|
||||
trio = ["trio (>=0.23)"]
|
||||
wmi = ["wmi (>=1.5.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "email-validator"
|
||||
version = "2.2.0"
|
||||
description = "A robust email address syntax and deliverability validation library."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631"},
|
||||
{file = "email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
dnspython = ">=2.0.0"
|
||||
idna = ">=2.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.115.14"
|
||||
@@ -721,4 +758,4 @@ standard = ["colorama (>=0.4) ; sys_platform == \"win32\"", "httptools (>=0.6.3)
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = ">=3.12"
|
||||
content-hash = "e9bc371ef3ba3a59fce2dbc0416fbb5be92bbccf98f36bd661ed55318975f3a1"
|
||||
content-hash = "78991183ad2dfe443ab27c24820d79f492bb74ef261393364004ba457a42ba65"
|
||||
|
||||
@@ -21,6 +21,7 @@ dependencies = [
|
||||
"fastapi (>=0.115.14,<0.116.0)",
|
||||
"pyjwt (>=2.10.1,<3.0.0)",
|
||||
"passlib (>=1.7.4,<2.0.0)",
|
||||
"email-validator (>=2.2.0,<3.0.0)",
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from fastapi import APIRouter
|
||||
from src.api.users import router as users_router
|
||||
from src.api.tasks import router as tasks_router
|
||||
|
||||
router = APIRouter()
|
||||
from src.api.v1 import router as v1_router
|
||||
from src.core.settings import settings
|
||||
|
||||
router = APIRouter(prefix=settings.api.prefix)
|
||||
|
||||
router.include_router(router=v1_router)
|
||||
|
||||
router.include_router(router=users_router)
|
||||
router.include_router(router=tasks_router)
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Annotated, AsyncGenerator
|
||||
from fastapi import Depends
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.db.database import async_session_maker
|
||||
from src.core.database import async_session_maker
|
||||
|
||||
|
||||
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
||||
@@ -11,6 +11,6 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
||||
yield db
|
||||
|
||||
|
||||
DBDep = Annotated[AsyncSession, Depends(get_db)]
|
||||
sessionDep = Annotated[AsyncSession, Depends(get_db)]
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter(prefix="/users", tags=["Users"])
|
||||
11
src/api/v1/__init__.py
Normal file
11
src/api/v1/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
||||
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.core.settings import settings
|
||||
|
||||
router = APIRouter(prefix=settings.api.v1.prefix)
|
||||
|
||||
router.include_router(router=auth_router)
|
||||
router.include_router(router=users_router)
|
||||
router.include_router(router=tasks_router)
|
||||
13
src/api/v1/auth.py
Normal file
13
src/api/v1/auth.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from src.api.dependacies.db_dep import sessionDep
|
||||
from src.schemas.users import UserCreate
|
||||
from src.core.settings import settings
|
||||
from src.services.auth import AuthService
|
||||
|
||||
router = APIRouter(prefix=settings.api.v1.auth, tags=['Auth'])
|
||||
|
||||
|
||||
@router.post(path='/signup')
|
||||
async def registration(session: sessionDep, credential: UserCreate):
|
||||
await AuthService(session).registration(credential)
|
||||
5
src/api/v1/users.py
Normal file
5
src/api/v1/users.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from src.core.settings import settings
|
||||
|
||||
router = APIRouter(prefix=settings.api.v1.users, tags=["Users"])
|
||||
@@ -4,7 +4,7 @@ from sqlalchemy import TIMESTAMP, func
|
||||
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
|
||||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
||||
|
||||
from src.settings import settings
|
||||
from src.core.settings import settings
|
||||
|
||||
engine = create_async_engine(settings.db.url, echo=True)
|
||||
|
||||
@@ -7,6 +7,17 @@ BASE_DIR = Path(__file__).parent
|
||||
DB_PATH = BASE_DIR / "db/taskncoffee.db"
|
||||
|
||||
|
||||
class ApiV1Prefix(BaseModel):
|
||||
prefix: str = "/v1"
|
||||
auth: str = "/auth"
|
||||
users: str = "/users"
|
||||
|
||||
|
||||
class ApiPrefix(BaseModel):
|
||||
prefix: str = "/api"
|
||||
v1: ApiV1Prefix = ApiV1Prefix()
|
||||
|
||||
|
||||
class DbSettings(BaseModel):
|
||||
url: str = f"sqlite+aiosqlite:///{DB_PATH}"
|
||||
|
||||
@@ -22,7 +33,7 @@ class AccessToken(BaseSettings):
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_file='.env', env_file_encoding='utf-8')
|
||||
api: ApiPrefix = ApiPrefix()
|
||||
db: DbSettings = DbSettings()
|
||||
access_token: AccessToken = AccessToken()
|
||||
|
||||
@@ -11,4 +11,4 @@ app = FastAPI()
|
||||
app.include_router(router=router)
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run("src.main:app", port=5000, log_level="info", reload=True)
|
||||
uvicorn.run("src.main:app", port=8000, log_level="info", reload=True)
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Optional, TYPE_CHECKING
|
||||
from sqlalchemy import ForeignKey, Text, Date, Enum, String
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from src.db.database import Base
|
||||
from src.core.database import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.models.users import UsersORM
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from sqlalchemy import String, BigInteger, Integer, Boolean, VARCHAR
|
||||
from sqlalchemy import String, BigInteger, Integer, Boolean
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from src.db.database import Base
|
||||
from src.core.database import Base
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from src.models.tasks import TasksORM
|
||||
|
||||
0
src/repository/__init__.py
Normal file
0
src/repository/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
from pydantic import BaseModel, EmailStr
|
||||
|
||||
|
||||
class UserRead(BaseModel):
|
||||
username: str
|
||||
email: EmailStr | None
|
||||
is_active: bool
|
||||
is_superuser: bool
|
||||
|
||||
|
||||
class UserCreate(BaseModel):
|
||||
username: str
|
||||
email: EmailStr | None = None
|
||||
password: str
|
||||
|
||||
|
||||
0
src/services/__init__.py
Normal file
0
src/services/__init__.py
Normal file
11
src/services/auth.py
Normal file
11
src/services/auth.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from src.schemas.users import UserCreate
|
||||
from src.services.base import BaseService
|
||||
|
||||
|
||||
class AuthService(BaseService):
|
||||
|
||||
|
||||
async def registration(self, data: UserCreate):
|
||||
...
|
||||
|
||||
|
||||
9
src/services/base.py
Normal file
9
src/services/base.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from src.utils.db_manager import DBManager
|
||||
|
||||
|
||||
class BaseService:
|
||||
session: DBManager | None
|
||||
|
||||
def __init__(self, session: DBManager):
|
||||
self.session = session
|
||||
|
||||
9
src/utils/auth_manager.py
Normal file
9
src/utils/auth_manager.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from passlib.context import CryptContext
|
||||
|
||||
|
||||
class AuthManger:
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
|
||||
@classmethod
|
||||
def verify_password(cls, plain_password, hashed_password):
|
||||
return cls.pwd_context.verify(plain_password, hashed_password)
|
||||
12
src/utils/db_manager.py
Normal file
12
src/utils/db_manager.py
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
class DBManager:
|
||||
def __init__(self, session_factory):
|
||||
self.session_factory = session_factory
|
||||
|
||||
async def __aenter__(self):
|
||||
self.session = self.session_factory()
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
await self.session.rollback()
|
||||
await self.session.close()
|
||||
Reference in New Issue
Block a user