feat: implement remaining repo methods for chatbot and quote

This commit is contained in:
cătălin 2025-03-07 00:28:05 +01:00
commit 4b7ffbc914
No known key found for this signature in database
10 changed files with 352 additions and 177 deletions

View file

@ -13,7 +13,7 @@ app = Typer()
@app.command()
def import_vod_cc(channel_name: str, youtube_url: str, db_path: Path | None = None):
def import_vod(channel_name: str, youtube_url: str, db_path: Path | None = None):
logger.info(f"Importing VOD closed captions for {channel_name} from {youtube_url}")
s = Settings.get(db_filepath=db_path)
import_from_vod_action = ImportFromVODAction(

View file

@ -7,6 +7,7 @@ from huesoporro.actions.chatbot.create_or_update_chatbot import (
from huesoporro.actions.chatbot.get_chatbot_by_user_id import GetChatbotByUserIdAction
from huesoporro.actions.users.authenticate_user import AuthenticateUserAction
from huesoporro.actions.users.get_user_by_jwt import GetUserByJWTAction
from huesoporro.bot import BotsManager
from huesoporro.infra.authenticator import TwitchAuthenticator
from huesoporro.infra.repos import ChatbotRepo, UserRepo
from huesoporro.libs.db import MarkovDatabase
@ -28,29 +29,29 @@ from huesoporro.svc.users_svcs import (
)
def get_settings() -> Settings:
async def get_settings() -> Settings:
return Settings.get()
def get_authenticator(s: Settings) -> TwitchAuthenticator:
async def get_authenticator(s: Settings) -> TwitchAuthenticator:
return TwitchAuthenticator(s=s)
def get_chatbot_repo(s: Settings):
async def get_chatbot_repo(s: Settings):
return ChatbotRepo(s=s)
def get_get_chatbot_by_user_id_svc(chatbot_repo: ChatbotRepo):
async def get_get_chatbot_by_user_id_svc(chatbot_repo: ChatbotRepo):
return GetChatbotByUserIdSvc(repo=chatbot_repo)
def get_get_tokens_by_auth_code_svc(
async def get_get_tokens_by_auth_code_svc(
twitch_authenticator: TwitchAuthenticator, s: Settings
):
return GetTwitchAuthByAuthCodeSvc(s=s, authenticator=twitch_authenticator)
def get_create_chatbot_svc(chatbot_repo: ChatbotRepo):
async def get_create_chatbot_svc(chatbot_repo: ChatbotRepo):
return CreateChatbotSvc(repo=chatbot_repo)
@ -58,19 +59,19 @@ async def get_user_repo(s: Settings):
return UserRepo(s=s)
def get_create_user_svc(user_repo: UserRepo):
async def get_create_user_svc(user_repo: UserRepo):
return CreateUserSvc(user_repo=user_repo)
def get_update_user_svc(user_repo: UserRepo):
async def get_update_user_svc(user_repo: UserRepo):
return UpdateUserSvc(user_repo=user_repo)
def get_refresh_token_svc(twitch_authenticator: TwitchAuthenticator):
async def get_refresh_token_svc(twitch_authenticator: TwitchAuthenticator):
return RefreshTokenSvc(twitch_authenticator=twitch_authenticator)
def get_is_valid_token_svc(twitch_authenticator: TwitchAuthenticator):
async def get_is_valid_token_svc(twitch_authenticator: TwitchAuthenticator):
return IsValidTokenSvc(authenticator=twitch_authenticator)
@ -118,11 +119,11 @@ async def get_sentences_storer_svc(db: MarkovDatabase):
return SentenceStorerSvc(db=db)
def get_update_chatbot_svc(chatbot_repo: ChatbotRepo):
async def get_update_chatbot_svc(chatbot_repo: ChatbotRepo):
return UpdateChatbotSvc(repo=chatbot_repo)
def get_create_or_update_chatbot_action(
async def get_create_or_update_chatbot_action(
create_chatbot_svc: CreateChatbotSvc,
update_chatbot_svc: UpdateChatbotSvc,
get_chatbot_by_user_id_svc: GetChatbotByUserIdSvc,
@ -134,7 +135,7 @@ def get_create_or_update_chatbot_action(
)
def get_get_chatbot_by_user_id_action(
async def get_get_chatbot_by_user_id_action(
get_chatbot_by_user_id_svc: GetChatbotByUserIdSvc,
):
return GetChatbotByUserIdAction(
@ -158,6 +159,10 @@ async def get_authenticate_action(
)
async def get_bot_manager(s: Settings):
return BotsManager(s=s)
async def chatbot(
get_chatbot_by_user_id_action: GetChatbotByUserIdAction,
create_or_update_chatbot_action: CreateOrUpdateChatbotAction,

View file

@ -11,6 +11,7 @@ from apps.httpapi.litestar.dependencies import (
authenticate,
get_authenticate_action,
get_authenticator,
get_bot_manager,
get_chatbot_repo,
get_create_chatbot_svc,
get_create_or_update_chatbot_action,
@ -43,12 +44,11 @@ from apps.httpapi.litestar.routes.api import (
save_bot_settings,
)
from apps.httpapi.litestar.routes.auth import get_code, login
from huesoporro.bot import BotsManager
from huesoporro.settings import Settings
@get("/healthz")
def get_health() -> dict:
async def get_health() -> dict:
return {"status": "ok"}
@ -89,7 +89,7 @@ def create_app():
"s": Provide(get_settings, use_cache=True),
"a": Provide(get_authenticator, use_cache=True),
"user": Provide(authenticate),
"bm": Provide(BotsManager, use_cache=True),
"bm": Provide(get_bot_manager, use_cache=True),
"sss": Provide(get_sentences_storer_svc),
"twitch_authenticator": Provide(get_authenticator),
"authenticate_action": Provide(get_authenticate_action),
@ -115,7 +115,6 @@ def create_app():
app = create_app()
if __name__ == "__main__":
s = Settings.get()
config = uvicorn.Config("main:app", host=s.port, port=s.port, log_level="info")

View file

@ -42,9 +42,7 @@ class IRepo(BaseModel, ABC, Generic[T]):
pass # pragma: no cover
@abstractmethod
async def list(
self, obj: T, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[T]:
async def list(self, offset: int = 0, limit: int = 10, auto_commit=True) -> list[T]:
pass # pragma: no cover
@ -153,7 +151,7 @@ class UserRepo(IRepo[User]):
)
async def list( # type: ignore[empty-body]
self, obj: User, offset: int = 0, limit: int = 10, auto_commit=True
self, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[User]:
pass # pragma: no cover
@ -174,6 +172,8 @@ class QuoteRepo(IRepo[Quote]):
)
async def create(self, obj: Quote, auto_commit=True) -> Quote:
if await self.get_by_quote(obj.quote):
raise ValueError(f"Quote {obj.quote} already exists")
async with (
self.get_client(auto_commit=auto_commit) as db,
await db.execute(
@ -196,18 +196,81 @@ class QuoteRepo(IRepo[Quote]):
return self._deserialize(data)
async def update(self, obj: Quote, auto_commit=True) -> Quote: # type: ignore[empty-body]
pass # pragma: no cover
if not await self.get_by_id(obj.id):
raise ValueError(f"Quote {obj.id} does not exist")
async with (
self.get_client(auto_commit=auto_commit) as db,
await db.execute(
"""
UPDATE quotes
SET quote = ?,
author = ?,
channel = ?,
last_updated_at = ?
WHERE id = ?
RETURNING *
""",
(
obj.quote,
obj.author,
obj.channel_name,
utils.get_utc_now(),
obj.id.hex,
),
) as cursor,
):
data = await cursor.fetchone()
return self._deserialize(data)
async def delete(self, obj: Quote, auto_commit=True):
pass # pragma: no cover
async with self.get_client(auto_commit=auto_commit) as db:
await db.execute(
"""
DELETE FROM quotes WHERE id = ?
""",
(obj.id.hex,),
)
async def get_by_id(self, obj_id: UUID, auto_commit=True) -> Quote | None: # type: ignore[empty-body]
pass # pragma: no cover
async with (
self.get_client(auto_commit=auto_commit) as db,
db.execute(
"""
SELECT * FROM quotes WHERE id = ?
""",
(obj_id.hex,),
) as cursor,
):
data = await cursor.fetchone()
if not data:
return None
return self._deserialize(data)
async def get_by_quote(self, quote: str, auto_commit=True) -> Quote | None:
async with (
self.get_client(auto_commit=auto_commit) as db,
db.execute(
"""
SELECT * FROM quotes WHERE quote = ?
""",
(quote,),
) as cursor,
):
data = await cursor.fetchone()
if not data:
return None
return self._deserialize(data)
async def list( # type: ignore[empty-body]
self, obj: T, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[T]:
pass # pragma: no cover
self, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[Quote]:
async with self.get_client() as db:
db.row_factory = aiosqlite.Row
async with db.execute(
"SELECT * FROM quotes LIMIT ? OFFSET ?", (limit, offset)
) as cursor:
results = await cursor.fetchall()
return [self._deserialize(result) for result in results]
async def get_random(self, channel_name: str, auto_commit=True) -> Quote | None:
async with (
@ -298,11 +361,22 @@ class ChatbotRepo(IRepo[Chatbot]):
data = await cursor.fetchone()
return self._deserialize(data)
async def delete(self, obj: T, auto_commit=True):
pass # pragma: no cover
async def delete(self, obj: Chatbot, auto_commit=True):
if not await self.get_by_id(obj.id):
raise ValueError(f"Chatbot {obj.id} does not exist")
async with self.get_client() as db:
await db.execute("DELETE FROM chatbot WHERE id = ?", (obj.id.hex,))
async def get_by_id(self, obj_id: UUID, auto_commit=True) -> Chatbot | None: # type: ignore[empty-body]
pass # pragma: no cover
async with self.get_client() as db:
db.row_factory = aiosqlite.Row
async with db.execute(
"SELECT * FROM chatbot WHERE id = ?", (obj_id.hex,)
) as cursor:
result = await cursor.fetchone()
if not result:
return None
return self._deserialize(result)
async def get_by_user_id(self, user_id: UUID) -> Chatbot | None:
async with self.get_client() as db:
@ -316,6 +390,12 @@ class ChatbotRepo(IRepo[Chatbot]):
return self._deserialize(result)
async def list( # type: ignore[empty-body]
self, obj: T, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[T]:
pass # pragma: no cover
self, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[Chatbot]:
async with self.get_client() as db:
db.row_factory = aiosqlite.Row
async with db.execute(
"SELECT * FROM chatbot LIMIT ? OFFSET ?", (limit, offset)
) as cursor:
results = await cursor.fetchall()
return [self._deserialize(result) for result in results]