Skip to content

Commit

Permalink
style: reorder functions
Browse files Browse the repository at this point in the history
  • Loading branch information
zobweyt committed Nov 14, 2024
1 parent b7f7bfd commit 0d4e238
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 98 deletions.
24 changes: 12 additions & 12 deletions src/api/auth/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,6 @@
router = APIRouter(prefix="/auth", tags=["Authentication"])


@router.post("/register", status_code=status.HTTP_201_CREATED)
async def register(args: UserRegistrationRequest, service: UserServiceDepends) -> AccessTokenResponse:
if service.is_email_registered(args.email):
raise HTTPException(status.HTTP_409_CONFLICT, _("Email already registered."))
if not expire_otp_if_correct(args.email, args.otp):
raise HTTPException(status.HTTP_406_NOT_ACCEPTABLE, _("The One-Time Password (OTP) is incorrect or expired."))

user = service.register_user(args)

return create_access_token(user.id)


@router.post("/login")
async def login(form: OAuth2PasswordRequestFormDepends, service: UserServiceDepends) -> AccessTokenResponse:
email = form.username # The OAuth2 spec requires the exact name `username`.
Expand All @@ -38,6 +26,18 @@ async def login(form: OAuth2PasswordRequestFormDepends, service: UserServiceDepe
return create_access_token(user.id)


@router.post("/register", status_code=status.HTTP_201_CREATED)
async def register(args: UserRegistrationRequest, service: UserServiceDepends) -> AccessTokenResponse:
if service.is_email_registered(args.email):
raise HTTPException(status.HTTP_409_CONFLICT, _("Email already registered."))
if not expire_otp_if_correct(args.email, args.otp):
raise HTTPException(status.HTTP_406_NOT_ACCEPTABLE, _("The One-Time Password (OTP) is incorrect or expired."))

user = service.register_user(args)

return create_access_token(user.id)


@router.patch("/reset-password")
def reset_password(args: UserPasswordResetRequest, service: UserServiceDepends) -> AccessTokenResponse:
user = service.get_user_by_email(args.email)
Expand Down
16 changes: 8 additions & 8 deletions src/api/authors/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
router = APIRouter(prefix="/authors", tags=["Authors"])


@router.post("/", response_model=AuthorResponse, status_code=status.HTTP_201_CREATED)
def create_author(args: AuthorCreateRequest, current_user: CurrentUser, service: AuthorServiceDepends):
if service.exists(args.name):
raise HTTPException(status.HTTP_409_CONFLICT, _("An author with the name '%s' already exists." % (args.name,)))

return service.create_author(name=args.name, created_by_user_id=current_user.id)


@router.get("/{name}", response_model=AuthorResponse)
def get_author(name: str, service: AuthorServiceDepends):
author = service.get_author_by_name(name)
Expand All @@ -27,11 +35,3 @@ def get_authors(search_params: SearchParamsDepends, service: AuthorServiceDepend
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No authors found matching the provided search parameters."))

return authors


@router.post("/", response_model=AuthorResponse, status_code=status.HTTP_201_CREATED)
def create_author(args: AuthorCreateRequest, current_user: CurrentUser, service: AuthorServiceDepends):
if service.exists(args.name):
raise HTTPException(status.HTTP_409_CONFLICT, _("An author with the name '%s' already exists." % (args.name,)))

return service.create_author(name=args.name, created_by_user_id=current_user.id)
22 changes: 11 additions & 11 deletions src/api/authors/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@ class AuthorService:
def __init__(self, session: SessionDepends) -> None:
self.session = session

def get_author_by_name(self, name: str) -> Author | None:
return self.session.query(Author).filter(Author.name == name).first()
def create_author(self, *, name: str, created_by_user_id: int) -> Author:
author = Author(name=name, created_by_user_id=created_by_user_id)

self.session.add(author)
self.session.commit()
self.session.refresh(author)

return author

def get_author_by_id(self, author_id: int) -> Author | None:
return self.session.get(Author, author_id)

def get_author_by_name(self, name: str) -> Author | None:
return self.session.query(Author).filter(Author.name == name).first()

def get_authors(self, search_params: SearchParams) -> list[Author]:
query = self.session.query(Author)

Expand All @@ -23,14 +32,5 @@ def get_authors(self, search_params: SearchParams) -> list[Author]:

return query.order_by(Author.name).offset(search_params.offset).limit(search_params.limit).all()

def create_author(self, *, name: str, created_by_user_id: int) -> Author:
author = Author(name=name, created_by_user_id=created_by_user_id)

self.session.add(author)
self.session.commit()
self.session.refresh(author)

return author

def exists(self, name: str) -> bool:
return self.session.query(exists().where(Author.name == name)).scalar()
81 changes: 44 additions & 37 deletions src/api/collections/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,66 +12,56 @@
router = APIRouter(prefix="/collections", tags=["Collections"])


@router.get("/{id}", response_model=CollectionResponse)
def get_collection(id: int, service: CollectionServiceDepends, current_user: CurrentUserOrNone):
collection = service.get_collection(id)

if not collection:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (id,)))

is_private = collection.visibility == Collection.Visibility.PRIVATE
has_access = current_user and current_user.id == collection.created_by_user_id

if is_private and not has_access:
raise HTTPException(status.HTTP_403_FORBIDDEN, _("Access denied to this private collection."))

return collection


@router.get("/", response_model=list[CollectionResponse])
def get_public_collections(search_params: SearchParamsDepends, service: CollectionServiceDepends):
collections = service.get_public_collections(search_params)

if not collections:
raise HTTPException(
status.HTTP_404_NOT_FOUND,
_("No collections found matching the provided search parameters."),
)

return collections


@router.post("/", response_model=CollectionResponse, status_code=status.HTTP_201_CREATED)
def create_collection(args: CollectionCreateRequest, current_user: CurrentUser, service: CollectionServiceDepends):
return service.create_collection(args, created_by_user_id=current_user.id)


@router.patch("/{id}", response_model=CollectionResponse)
@router.patch("/{collection_id}", response_model=CollectionResponse)
def update_collection(
id: int, args: CollectionUpdateRequest, current_user: CurrentUser, service: CollectionServiceDepends
collection_id: int,
args: CollectionUpdateRequest,
current_user: CurrentUser,
service: CollectionServiceDepends,
):
collection = service.get_collection(id)
collection = service.get_collection(collection_id)

if not collection:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (id,)))
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (collection_id,)))
if collection.created_by_user_id != current_user.id:
raise HTTPException(status.HTTP_403_FORBIDDEN, _("You do not have permission to modify this collection."))

return service.update_collection(collection, args)


@router.delete("/{id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_collection(id: int, current_user: CurrentUser, service: CollectionServiceDepends):
collection = service.get_collection(id)
@router.delete("/{collection_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_collection(collection_id: int, current_user: CurrentUser, service: CollectionServiceDepends):
collection = service.get_collection(collection_id)

if not collection:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (id,)))
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (collection_id,)))
if collection.created_by_user_id != current_user.id:
raise HTTPException(status.HTTP_403_FORBIDDEN, _("You do not have permission to modify this collection."))

service.delete_collection(collection)


@router.get("/{collection_id}", response_model=CollectionResponse)
def get_collection(collection_id: int, service: CollectionServiceDepends, current_user: CurrentUserOrNone):
collection = service.get_collection(collection_id)

if not collection:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (collection_id,)))

is_private = collection.visibility == Collection.Visibility.PRIVATE
has_access = current_user and current_user.id == collection.created_by_user_id

if is_private and not has_access:
raise HTTPException(status.HTTP_403_FORBIDDEN, _("Access denied to this private collection."))

return collection


@router.get("/{collection_id}/quotes", response_model=list[QuoteResponse])
def get_collection_quotes(
collection_id: int,
Expand All @@ -94,6 +84,19 @@ def get_collection_quotes(
return quote_service.get_collection_quotes(collection_id, search_params)


@router.get("/", response_model=list[CollectionResponse])
def get_public_collections(search_params: SearchParamsDepends, service: CollectionServiceDepends):
collections = service.get_public_collections(search_params)

if not collections:
raise HTTPException(
status.HTTP_404_NOT_FOUND,
_("No collections found matching the provided search parameters."),
)

return collections


@router.post("/{collection_id}/quotes", response_model=QuoteCollectionsResponse, status_code=status.HTTP_201_CREATED)
def add_quote_to_collection(
collection_id: int,
Expand All @@ -111,6 +114,8 @@ def add_quote_to_collection(

if not collection:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (collection_id,)))
if quote.id in (quote.id for quote in collection.quotes):
raise HTTPException(status.HTTP_409_CONFLICT, _("Quote with the ID %s is in collection." % (quote_id,)))

if current_user.id != collection.created_by_user_id:
raise HTTPException(status.HTTP_403_FORBIDDEN, _("Access denied to this private collection."))
Expand All @@ -135,6 +140,8 @@ def remove_quote_from_collection(

if not collection:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No collection found with the ID %s." % (collection_id,)))
if quote.id not in (quote.id for quote in collection.quotes):
raise HTTPException(status.HTTP_409_CONFLICT, _("Quote with the ID %s is not in collection." % (quote_id,)))

if current_user.id != collection.created_by_user_id:
raise HTTPException(status.HTTP_403_FORBIDDEN, _("Access denied to this private collection."))
Expand Down
15 changes: 7 additions & 8 deletions src/api/collections/service.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from sqlalchemy import or_
from sqlalchemy.orm import Query

from src.api.collections.models import Collection
from src.api.collections.models import Collection, QuoteCollection
from src.api.collections.schemas import CollectionCreateRequest, CollectionUpdateRequest
from src.api.params import SearchParams
from src.api.quotes.models import Quote
Expand All @@ -12,8 +12,8 @@ class CollectionService:
def __init__(self, session: SessionDepends) -> None:
self.session = session

def get_collection(self, id: int) -> Collection | None:
return self.session.get(Collection, id)
def get_collection(self, collection_id: int) -> Collection | None:
return self.session.get(Collection, collection_id)

def get_public_collections(self, search_params: SearchParams) -> list[Collection]:
query = self.session.query(Collection).filter(Collection.visibility == Collection.Visibility.PUBLIC)
Expand Down Expand Up @@ -61,17 +61,16 @@ def delete_collection(self, collection: Collection) -> None:
self.session.commit()

def add_quote_to_collection(self, quote: Quote, collection: Collection) -> Quote:
collection.quotes.append(quote)
quote_collection = QuoteCollection(quote_id=quote.id, collection_id=collection.id)

self.session.add(collection)
self.session.add(quote_collection)
self.session.commit()

self.session.refresh(quote)

return quote

def remove_quote_from_collection(self, quote: Quote, collection: Collection) -> None:
collection.quotes.remove(quote)
quote_collection = self.session.get(QuoteCollection, {"quote_id": quote.id, "collection_id": collection.id})

self.session.delete(quote_collection)
self.session.add(collection)
self.session.commit()
40 changes: 20 additions & 20 deletions src/api/quotes/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,6 @@
router = APIRouter(prefix="/quotes", tags=["Quotes"])


@router.get("/{quote_id}", response_model=QuoteCollectionsResponse)
def get_quote(quote_id: int, service: QuoteServiceDepends):
quote = service.get_quote_by_id(quote_id)

if not quote:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No quote found with the ID %s." % (quote_id,)))

return quote


@router.get("/", response_model=list[QuoteResponse])
def get_quotes(search_params: SearchParamsDepends, service: QuoteServiceDepends):
quotes = service.get_quotes(search_params)

if not quotes:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No quotes found matching the provided search parameters."))

return quotes


@router.post("/", response_model=QuoteResponse, status_code=status.HTTP_201_CREATED)
def create_quote(
args: QuoteCreateRequest,
Expand Down Expand Up @@ -64,3 +44,23 @@ def delete_quote(quote_id: int, current_user: CurrentUser, service: QuoteService
raise HTTPException(status.HTTP_403_FORBIDDEN, _("You do not have permission to modify this quote."))

service.delete_quote(quote)


@router.get("/{quote_id}", response_model=QuoteCollectionsResponse)
def get_quote(quote_id: int, service: QuoteServiceDepends):
quote = service.get_quote_by_id(quote_id)

if not quote:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No quote found with the ID %s." % (quote_id,)))

return quote


@router.get("/", response_model=list[QuoteResponse])
def get_quotes(search_params: SearchParamsDepends, service: QuoteServiceDepends):
quotes = service.get_quotes(search_params)

if not quotes:
raise HTTPException(status.HTTP_404_NOT_FOUND, _("No quotes found matching the provided search parameters."))

return quotes
4 changes: 2 additions & 2 deletions src/api/users/me/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def delete_current_user_avatar(current_user: CurrentUser, service: UserServiceDe
service.delete_avatar(current_user)


@router.get("/collections", response_model=list[CollectionResponse], tags=["Collections"])
@router.get("/collections", response_model=list[CollectionResponse])
def get_current_user_collections(
search_params: SearchParamsDepends,
current_user: CurrentUser,
Expand All @@ -104,7 +104,7 @@ def get_current_user_collections(
return collections


@router.get("/quotes", response_model=list[QuoteResponse], tags=["Quotes"])
@router.get("/quotes", response_model=list[QuoteResponse])
def get_current_user_quotes(
service: QuoteServiceDepends,
current_user: CurrentUser,
Expand Down

0 comments on commit 0d4e238

Please sign in to comment.