Spaces:
Runtime error
Runtime error
Ashok Kumar Bhati commited on
Commit ·
cc7f27e
1
Parent(s): 08af573
Add user register API endpoint
Browse files- migrations/versions/8652e8501339_add_user_and_slack_team.py +50 -0
- src/app.py +22 -1
- src/controllers/__init__.py +3 -1
- src/controllers/_user_controller.py +28 -0
- src/models/__init__.py +7 -0
- src/models/_base.py +3 -0
- src/models/_slack_team.py +28 -0
- src/models/_user.py +36 -0
- src/repositories/__init__.py +8 -0
- src/repositories/_base_repository.py +81 -0
- src/repositories/_config.py +29 -0
- src/repositories/_slack_team_repository.py +8 -0
- src/repositories/_user_repository.py +16 -0
- src/services/__init__.py +2 -1
- src/services/_slack_team_service.py +23 -0
- src/services/_user_service.py +48 -0
migrations/versions/8652e8501339_add_user_and_slack_team.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""add user and slack team
|
| 2 |
+
|
| 3 |
+
Revision ID: 8652e8501339
|
| 4 |
+
Revises:
|
| 5 |
+
Create Date: 2024-10-24 16:52:59.936776
|
| 6 |
+
|
| 7 |
+
"""
|
| 8 |
+
from typing import Sequence, Union
|
| 9 |
+
|
| 10 |
+
from alembic import op
|
| 11 |
+
import sqlalchemy as sa
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
# revision identifiers, used by Alembic.
|
| 15 |
+
revision: str = '8652e8501339'
|
| 16 |
+
down_revision: Union[str, None] = None
|
| 17 |
+
branch_labels: Union[str, Sequence[str], None] = None
|
| 18 |
+
depends_on: Union[str, Sequence[str], None] = None
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def upgrade() -> None:
|
| 22 |
+
# ### commands auto generated by Alembic - please adjust! ###
|
| 23 |
+
op.create_table('slack_teams',
|
| 24 |
+
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
| 25 |
+
sa.Column('name', sa.String(), nullable=False),
|
| 26 |
+
sa.Column('slack_team_id', sa.String(), nullable=False),
|
| 27 |
+
sa.Column('token', sa.String(), nullable=False),
|
| 28 |
+
sa.Column('created_at', sa.DateTime(), nullable=False),
|
| 29 |
+
sa.PrimaryKeyConstraint('id')
|
| 30 |
+
)
|
| 31 |
+
op.create_table('users',
|
| 32 |
+
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
|
| 33 |
+
sa.Column('name', sa.String(), nullable=False),
|
| 34 |
+
sa.Column('content_delivery_frequency', sa.Enum('DAILY', 'WEEKLY', 'BI_WEEKLY', 'MONTHLY', name='contentdeliveryfrequency'), nullable=False),
|
| 35 |
+
sa.Column('slack_id', sa.String(), nullable=True),
|
| 36 |
+
sa.Column('slack_team_id', sa.Integer(), nullable=True),
|
| 37 |
+
sa.Column('email_id', sa.String(), nullable=False),
|
| 38 |
+
sa.Column('last_message_sent_at', sa.DateTime(), nullable=True),
|
| 39 |
+
sa.Column('created_at', sa.DateTime(), nullable=False),
|
| 40 |
+
sa.ForeignKeyConstraint(['slack_team_id'], ['slack_teams.id'], ),
|
| 41 |
+
sa.PrimaryKeyConstraint('id')
|
| 42 |
+
)
|
| 43 |
+
# ### end Alembic commands ###
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def downgrade() -> None:
|
| 47 |
+
# ### commands auto generated by Alembic - please adjust! ###
|
| 48 |
+
op.drop_table('users')
|
| 49 |
+
op.drop_table('slack_teams')
|
| 50 |
+
# ### end Alembic commands ###
|
src/app.py
CHANGED
|
@@ -9,7 +9,11 @@ from fastapi.middleware.cors import CORSMiddleware
|
|
| 9 |
|
| 10 |
from src.services import ContentDeliveryService
|
| 11 |
from src.utils import logger
|
| 12 |
-
from src.controllers import bot_router
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
scheduler = AsyncIOScheduler()
|
| 15 |
|
|
@@ -23,6 +27,21 @@ async def scheduled_job():
|
|
| 23 |
logger.error(e)
|
| 24 |
|
| 25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
def run_scheduler():
|
| 27 |
loop = asyncio.new_event_loop()
|
| 28 |
asyncio.set_event_loop(loop)
|
|
@@ -34,6 +53,7 @@ def run_scheduler():
|
|
| 34 |
async def lifespan(app: FastAPI):
|
| 35 |
try:
|
| 36 |
logger.info("Starting up the application...")
|
|
|
|
| 37 |
scheduler_thread = Thread(target=run_scheduler, daemon=True)
|
| 38 |
scheduler_thread.start()
|
| 39 |
logger.info("Application started successfully...")
|
|
@@ -63,3 +83,4 @@ async def check_health():
|
|
| 63 |
return {"response": "Service is healthy!"}
|
| 64 |
|
| 65 |
app.include_router(bot_router, prefix="/api/v1")
|
|
|
|
|
|
| 9 |
|
| 10 |
from src.services import ContentDeliveryService
|
| 11 |
from src.utils import logger
|
| 12 |
+
from src.controllers import bot_router, user_router
|
| 13 |
+
|
| 14 |
+
from alembic import command
|
| 15 |
+
from alembic.config import Config
|
| 16 |
+
from src.repositories import DatabaseConfig
|
| 17 |
|
| 18 |
scheduler = AsyncIOScheduler()
|
| 19 |
|
|
|
|
| 27 |
logger.error(e)
|
| 28 |
|
| 29 |
|
| 30 |
+
def run_upgrade(connection, alembic_config: Config):
|
| 31 |
+
alembic_config.attributes["connection"] = connection
|
| 32 |
+
command.upgrade(alembic_config, "head")
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
async def run_migrations():
|
| 36 |
+
logger.info("Running migrations if any...")
|
| 37 |
+
alembic_config = Config("alembic.ini")
|
| 38 |
+
alembic_config.set_main_option(
|
| 39 |
+
"sqlalchemy.url", os.getenv("SQLALCHEMY_DATABASE_URI")
|
| 40 |
+
)
|
| 41 |
+
async with DatabaseConfig.async_engine().begin() as session:
|
| 42 |
+
await session.run_sync(run_upgrade, alembic_config)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
def run_scheduler():
|
| 46 |
loop = asyncio.new_event_loop()
|
| 47 |
asyncio.set_event_loop(loop)
|
|
|
|
| 53 |
async def lifespan(app: FastAPI):
|
| 54 |
try:
|
| 55 |
logger.info("Starting up the application...")
|
| 56 |
+
await run_migrations()
|
| 57 |
scheduler_thread = Thread(target=run_scheduler, daemon=True)
|
| 58 |
scheduler_thread.start()
|
| 59 |
logger.info("Application started successfully...")
|
|
|
|
| 83 |
return {"response": "Service is healthy!"}
|
| 84 |
|
| 85 |
app.include_router(bot_router, prefix="/api/v1")
|
| 86 |
+
app.include_router(user_router, prefix="/api/v1")
|
src/controllers/__init__.py
CHANGED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
from ._bot_controller import BotController
|
|
|
|
| 2 |
|
| 3 |
bot_router = BotController().router
|
|
|
|
| 4 |
|
| 5 |
-
__all__ = ["bot_router"]
|
| 6 |
__version__ = "0.1.0"
|
| 7 |
__author__ = "Ashok Bhati"
|
|
|
|
| 1 |
from ._bot_controller import BotController
|
| 2 |
+
from ._user_controller import UserController
|
| 3 |
|
| 4 |
bot_router = BotController().router
|
| 5 |
+
user_router = UserController().router
|
| 6 |
|
| 7 |
+
__all__ = ["bot_router", "user_router"]
|
| 8 |
__version__ = "0.1.0"
|
| 9 |
__author__ = "Ashok Bhati"
|
src/controllers/_user_controller.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from fastapi import APIRouter, HTTPException
|
| 3 |
+
from src.utils import logger
|
| 4 |
+
from src.services import UserService
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class UserController:
|
| 8 |
+
def __init__(self):
|
| 9 |
+
self.service = UserService
|
| 10 |
+
self.router = APIRouter(prefix="/users", tags=["User"])
|
| 11 |
+
self.router.add_api_route("/", self.registerUser, methods=["POST"])
|
| 12 |
+
|
| 13 |
+
async def registerUser(self, user: dict):
|
| 14 |
+
logger.info(f"Received event: {user}")
|
| 15 |
+
try:
|
| 16 |
+
if not "email_id" in user:
|
| 17 |
+
raise HTTPException(status_code=400, detail="Missing email id")
|
| 18 |
+
if not "name" in user:
|
| 19 |
+
raise HTTPException(status_code=400, detail="Missing name")
|
| 20 |
+
async with self.service() as service:
|
| 21 |
+
user = await service.register_user(user)
|
| 22 |
+
return {"message": "User registered successfully", "user": user}
|
| 23 |
+
except HTTPException as e:
|
| 24 |
+
logger.warning(e)
|
| 25 |
+
raise e
|
| 26 |
+
except Exception as e:
|
| 27 |
+
logger.error(e)
|
| 28 |
+
raise HTTPException(status_code=500, detail=str(e))
|
src/models/__init__.py
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from ._base import Base
|
| 2 |
+
from ._user import User, ContentDeliveryFrequency
|
| 3 |
+
from ._slack_team import SlackTeam
|
| 4 |
+
|
| 5 |
+
__all__ = ["Base", "User", "ContentDeliveryFrequency", "SlackTeam"]
|
| 6 |
+
__version__ = "0.1.0"
|
| 7 |
+
__author__ = "Kanha Upadhyay"
|
src/models/_base.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sqlalchemy.orm import declarative_base
|
| 2 |
+
|
| 3 |
+
Base = declarative_base()
|
src/models/_slack_team.py
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from enum import Enum as PyEnum
|
| 2 |
+
|
| 3 |
+
from sqlalchemy import Column, DateTime, Enum, Integer, String, func
|
| 4 |
+
from sqlalchemy.orm import relationship
|
| 5 |
+
|
| 6 |
+
from ._base import Base
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class ContentDeliveryFrequency(PyEnum):
|
| 10 |
+
DAILY = "DAILY"
|
| 11 |
+
WEEKLY = "WEEKLY"
|
| 12 |
+
BI_WEEKLY = "BI_WEEKLY"
|
| 13 |
+
MONTHLY = "MONTHLY"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class SlackTeam(Base):
|
| 17 |
+
__tablename__ = "slack_teams"
|
| 18 |
+
|
| 19 |
+
id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
|
| 20 |
+
name = Column(String, nullable=False)
|
| 21 |
+
slack_team_id = Column(
|
| 22 |
+
String,
|
| 23 |
+
nullable=False,
|
| 24 |
+
)
|
| 25 |
+
token = Column(String, nullable=False)
|
| 26 |
+
created_at = Column(DateTime, nullable=False, default=func.now())
|
| 27 |
+
|
| 28 |
+
users = relationship("User", back_populates="slack_team")
|
src/models/_user.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from enum import Enum as PyEnum
|
| 2 |
+
|
| 3 |
+
from sqlalchemy import Column, DateTime, Enum, Integer, String, ForeignKey, func
|
| 4 |
+
from sqlalchemy.orm import relationship
|
| 5 |
+
|
| 6 |
+
from ._base import Base
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class ContentDeliveryFrequency(PyEnum):
|
| 10 |
+
DAILY = "DAILY"
|
| 11 |
+
WEEKLY = "WEEKLY"
|
| 12 |
+
BI_WEEKLY = "BI_WEEKLY"
|
| 13 |
+
MONTHLY = "MONTHLY"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class User(Base):
|
| 17 |
+
__tablename__ = "users"
|
| 18 |
+
|
| 19 |
+
id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
|
| 20 |
+
name = Column(String, nullable=False)
|
| 21 |
+
content_delivery_frequency = Column(
|
| 22 |
+
Enum(ContentDeliveryFrequency),
|
| 23 |
+
nullable=False,
|
| 24 |
+
default=ContentDeliveryFrequency.WEEKLY,
|
| 25 |
+
)
|
| 26 |
+
slack_id = Column(String, nullable=True)
|
| 27 |
+
slack_team_id = Column(
|
| 28 |
+
Integer,
|
| 29 |
+
ForeignKey("slack_teams.id"),
|
| 30 |
+
nullable=True,
|
| 31 |
+
)
|
| 32 |
+
email_id = Column(String, nullable=False)
|
| 33 |
+
last_message_sent_at = Column(DateTime, nullable=True)
|
| 34 |
+
created_at = Column(DateTime, nullable=False, default=func.now())
|
| 35 |
+
|
| 36 |
+
slack_team = relationship("SlackTeam", back_populates="users")
|
src/repositories/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from ._base_repository import BaseRepository
|
| 2 |
+
from ._config import DatabaseConfig
|
| 3 |
+
from ._user_repository import UserRepository
|
| 4 |
+
from ._slack_team_repository import SlackTeamRepository
|
| 5 |
+
|
| 6 |
+
__all__ = ["DatabaseConfig", "BaseRepository", "UserRepository", "SlackTeamRepository"]
|
| 7 |
+
__version__ = "0.1.0"
|
| 8 |
+
__author__ = "Kanha Upadhyay"
|
src/repositories/_base_repository.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from contextlib import asynccontextmanager
|
| 2 |
+
|
| 3 |
+
from sqlalchemy.future import select
|
| 4 |
+
|
| 5 |
+
from ._config import DatabaseConfig
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class BaseRepository:
|
| 9 |
+
def __init__(self, model=None):
|
| 10 |
+
self.__model = model
|
| 11 |
+
assert self.__model is not None, "model must be defined"
|
| 12 |
+
|
| 13 |
+
@asynccontextmanager
|
| 14 |
+
async def get_session(self):
|
| 15 |
+
async with DatabaseConfig.async_session() as session:
|
| 16 |
+
yield session
|
| 17 |
+
|
| 18 |
+
async def execute(self, query):
|
| 19 |
+
async with self.get_session() as session:
|
| 20 |
+
result = await session.execute(query)
|
| 21 |
+
return result
|
| 22 |
+
|
| 23 |
+
async def create(self, kwargs: dict):
|
| 24 |
+
async with self.get_session() as session:
|
| 25 |
+
instance = self.__model(**kwargs)
|
| 26 |
+
session.add(instance)
|
| 27 |
+
await session.commit()
|
| 28 |
+
await session.refresh(instance)
|
| 29 |
+
return instance
|
| 30 |
+
|
| 31 |
+
async def get_all(
|
| 32 |
+
self,
|
| 33 |
+
page: int = 1,
|
| 34 |
+
page_size: int = 10,
|
| 35 |
+
filter_by: dict = None,
|
| 36 |
+
order_by: dict = None,
|
| 37 |
+
):
|
| 38 |
+
async with self.get_session() as session:
|
| 39 |
+
offset = (page - 1) * page_size
|
| 40 |
+
query = select(self.__model).offset(offset).limit(page_size)
|
| 41 |
+
if filter_by:
|
| 42 |
+
query = query.filter_by(**filter_by)
|
| 43 |
+
if order_by:
|
| 44 |
+
for field, direction in order_by.items():
|
| 45 |
+
if direction == "asc":
|
| 46 |
+
query = query.order_by(getattr(self.__model, field).asc())
|
| 47 |
+
elif direction == "desc":
|
| 48 |
+
query = query.order_by(getattr(self.__model, field).desc())
|
| 49 |
+
result = await session.execute(query)
|
| 50 |
+
return [row for row in result.scalars()]
|
| 51 |
+
|
| 52 |
+
async def get(self, id, filter_by: dict = None):
|
| 53 |
+
async with self.get_session() as session:
|
| 54 |
+
query = select(self.__model).where(self.__model.id == id)
|
| 55 |
+
if filter_by:
|
| 56 |
+
query = query.filter_by(**filter_by)
|
| 57 |
+
result = await session.execute(query)
|
| 58 |
+
result = result.scalar()
|
| 59 |
+
if result:
|
| 60 |
+
return result
|
| 61 |
+
raise Exception(f"{self.__model.__name__} not found")
|
| 62 |
+
|
| 63 |
+
async def patch(self, id, **kwargs: dict):
|
| 64 |
+
async with self.get_session() as session:
|
| 65 |
+
instance = await session.get(self.__model, id)
|
| 66 |
+
if instance:
|
| 67 |
+
for key, value in kwargs.items():
|
| 68 |
+
setattr(instance, key, value)
|
| 69 |
+
await session.commit()
|
| 70 |
+
await session.refresh(instance)
|
| 71 |
+
return instance
|
| 72 |
+
raise Exception(f"{self.__model.__name__} not found")
|
| 73 |
+
|
| 74 |
+
async def delete(self, id):
|
| 75 |
+
async with self.get_session() as session:
|
| 76 |
+
instance = await session.get(self.__model, id)
|
| 77 |
+
if instance:
|
| 78 |
+
await session.delete(instance)
|
| 79 |
+
await session.commit()
|
| 80 |
+
return True
|
| 81 |
+
raise Exception(f"{self.__model.__name__} not found")
|
src/repositories/_config.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from contextlib import asynccontextmanager
|
| 3 |
+
|
| 4 |
+
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class DatabaseConfig:
|
| 8 |
+
@classmethod
|
| 9 |
+
def async_engine(cls):
|
| 10 |
+
return create_async_engine(
|
| 11 |
+
os.getenv("SQLALCHEMY_DATABASE_URI"), pool_pre_ping=True, pool_recycle=3600
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
@classmethod
|
| 15 |
+
@asynccontextmanager
|
| 16 |
+
async def async_session(cls):
|
| 17 |
+
engine = cls.async_engine()
|
| 18 |
+
session_factory = async_sessionmaker(
|
| 19 |
+
bind=engine,
|
| 20 |
+
autoflush=False,
|
| 21 |
+
autocommit=False,
|
| 22 |
+
expire_on_commit=False,
|
| 23 |
+
)
|
| 24 |
+
session = session_factory()
|
| 25 |
+
try:
|
| 26 |
+
yield session
|
| 27 |
+
finally:
|
| 28 |
+
await session.close()
|
| 29 |
+
await engine.dispose()
|
src/repositories/_slack_team_repository.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from src.models import SlackTeam
|
| 2 |
+
|
| 3 |
+
from ._base_repository import BaseRepository
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class SlackTeamRepository(BaseRepository):
|
| 7 |
+
def __init__(self):
|
| 8 |
+
super().__init__(model=SlackTeam)
|
src/repositories/_user_repository.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from sqlalchemy import select
|
| 2 |
+
|
| 3 |
+
from src.models import User
|
| 4 |
+
|
| 5 |
+
from ._base_repository import BaseRepository
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class UserRepository(BaseRepository):
|
| 9 |
+
def __init__(self):
|
| 10 |
+
super().__init__(model=User)
|
| 11 |
+
|
| 12 |
+
async def get_user_by_email(self, email: str):
|
| 13 |
+
query = select(User).where(User.email == email)
|
| 14 |
+
result = await self.execute(query)
|
| 15 |
+
result = result.scalar_one_or_none()
|
| 16 |
+
return result
|
src/services/__init__.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
from ._content_delivery_service import ContentDeliveryService
|
|
|
|
| 2 |
|
| 3 |
-
__all__ = ["ContentDeliveryService"]
|
| 4 |
__version__ = "0.1.0"
|
| 5 |
__author__ = "Ashok Bhati"
|
|
|
|
| 1 |
from ._content_delivery_service import ContentDeliveryService
|
| 2 |
+
from ._user_service import UserService
|
| 3 |
|
| 4 |
+
__all__ = ["ContentDeliveryService", "UserService"]
|
| 5 |
__version__ = "0.1.0"
|
| 6 |
__author__ = "Ashok Bhati"
|
src/services/_slack_team_service.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from src.repositories import SlackTeamRepository
|
| 2 |
+
|
| 3 |
+
from src.models import ContentDeliveryFrequency
|
| 4 |
+
import datetime
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class SlackTeamService:
|
| 8 |
+
def __init__(self):
|
| 9 |
+
self.slackTeam_repository = SlackTeamRepository()
|
| 10 |
+
|
| 11 |
+
async def __aenter__(self):
|
| 12 |
+
return self
|
| 13 |
+
|
| 14 |
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
| 15 |
+
pass
|
| 16 |
+
|
| 17 |
+
async def register_slackTeam(self, email: str):
|
| 18 |
+
return await self.slackTeam_repository.create(email=email)
|
| 19 |
+
|
| 20 |
+
async def get_slackTeam_token(self, slackTeam_id):
|
| 21 |
+
return await self.slackTeam_repository.get(
|
| 22 |
+
slackTeam_id, filter_by={"token": True}
|
| 23 |
+
)
|
src/services/_user_service.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from src.repositories import UserRepository
|
| 2 |
+
|
| 3 |
+
from src.models import ContentDeliveryFrequency
|
| 4 |
+
import datetime
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class UserService:
|
| 8 |
+
def __init__(self):
|
| 9 |
+
self.user_repository = UserRepository()
|
| 10 |
+
|
| 11 |
+
async def __aenter__(self):
|
| 12 |
+
return self
|
| 13 |
+
|
| 14 |
+
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
| 15 |
+
pass
|
| 16 |
+
|
| 17 |
+
async def register_user(self, user: dict) -> dict:
|
| 18 |
+
return await self.user_repository.create(user)
|
| 19 |
+
|
| 20 |
+
async def get_user_info_by_email(self, email: str):
|
| 21 |
+
return await self.user_repository.get_user_by_email(email=email)
|
| 22 |
+
|
| 23 |
+
async def update_user_slack_info(self, user_id, info):
|
| 24 |
+
return await self.user_repository.patch(user_id, info)
|
| 25 |
+
|
| 26 |
+
async def update_user_frequency(self, user_id, frequency: ContentDeliveryFrequency):
|
| 27 |
+
return await self.user_repository.patch(
|
| 28 |
+
user_id, {"content_delivery_frequency": frequency.value}
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
async def get_users_list(self):
|
| 32 |
+
return await self.user_repository.get_all()
|
| 33 |
+
|
| 34 |
+
async def get_user_last_message_time(self, user_id):
|
| 35 |
+
return await self.user_repository.get(
|
| 36 |
+
user_id, filter_by={"last_message_time": True}
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
async def update_user_last_message_time(self, user_id):
|
| 40 |
+
return await self.user_repository.patch(
|
| 41 |
+
id=user_id,
|
| 42 |
+
last_message_time=datetime.now(),
|
| 43 |
+
)
|
| 44 |
+
|
| 45 |
+
async def get_user_frequency(self, user_id):
|
| 46 |
+
return await self.user_repository.get(
|
| 47 |
+
user_id, filter_by={"content_delivery_frequency": True}
|
| 48 |
+
)
|