diff --git a/pyproject.toml b/pyproject.toml index bee1d93..7e82506 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ dependencies = [ "arq>=0.25.0", "bcrypt>=4.1.1", "psycopg2-binary>=2.9.9", - "fastcrud>=0.19.0", + "fastcrud>=0.19.1", "crudadmin>=0.4.2", "gunicorn>=23.0.0", "ruff>=0.11.13", diff --git a/src/app/api/dependencies.py b/src/app/api/dependencies.py index b9b0f64..5fead48 100644 --- a/src/app/api/dependencies.py +++ b/src/app/api/dependencies.py @@ -1,4 +1,4 @@ -from typing import Annotated, Any, cast +from typing import Annotated, Any from fastapi import Depends, HTTPException, Request from sqlalchemy.ext.asyncio import AsyncSession @@ -83,14 +83,14 @@ async def rate_limiter_dependency( user_id = user["id"] tier = await crud_tiers.get(db, id=user["tier_id"], schema_to_select=TierRead) if tier: - tier = cast(TierRead, tier) - rate_limit = await crud_rate_limits.get(db=db, tier_id=tier.id, path=path, schema_to_select=RateLimitRead) + rate_limit = await crud_rate_limits.get( + db=db, tier_id=tier["id"], path=path, schema_to_select=RateLimitRead + ) if rate_limit: - rate_limit = cast(RateLimitRead, rate_limit) - limit, period = rate_limit.limit, rate_limit.period + limit, period = rate_limit["limit"], rate_limit["period"] else: logger.warning( - f"User {user_id} with tier '{tier.name}' has no specific rate limit for path '{path}'. \ + f"User {user_id} with tier '{tier['name']}' has no specific rate limit for path '{path}'. \ Applying default rate limit." ) limit, period = DEFAULT_LIMIT, DEFAULT_PERIOD diff --git a/src/app/api/v1/posts.py b/src/app/api/v1/posts.py index c1b0945..95e39aa 100644 --- a/src/app/api/v1/posts.py +++ b/src/app/api/v1/posts.py @@ -1,4 +1,4 @@ -from typing import Annotated, Any, cast +from typing import Annotated, Any from fastapi import APIRouter, Depends, Request from fastcrud import PaginatedListResponse, compute_offset, paginated_response @@ -28,8 +28,6 @@ async def write_post( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) - if current_user["id"] != db_user["id"]: raise ForbiddenException() @@ -46,7 +44,7 @@ async def write_post( if post_read is None: raise NotFoundException("Created post not found") - return cast(dict[str, Any], post_read) + return post_read @router.get("/{username}/posts", response_model=PaginatedListResponse[PostRead]) @@ -66,7 +64,6 @@ async def read_posts( if not db_user: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) posts_data = await crud_posts.get_multi( db=db, offset=compute_offset(page, items_per_page), @@ -88,15 +85,13 @@ async def read_post( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) - db_post = await crud_posts.get( db=db, id=id, created_by_user_id=db_user["id"], is_deleted=False, schema_to_select=PostRead ) if db_post is None: raise NotFoundException("Post not found") - return cast(dict[str, Any], db_post) + return db_post @router.patch("/{username}/post/{id}") @@ -113,8 +108,6 @@ async def patch_post( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) - if current_user["id"] != db_user["id"]: raise ForbiddenException() @@ -122,8 +115,6 @@ async def patch_post( if db_post is None: raise NotFoundException("Post not found") - db_post = cast(dict[str, Any], db_post) - await crud_posts.update(db=db, object=values, id=id) return {"message": "Post updated"} @@ -141,8 +132,6 @@ async def erase_post( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) - if current_user["id"] != db_user["id"]: raise ForbiddenException() @@ -150,8 +139,6 @@ async def erase_post( if db_post is None: raise NotFoundException("Post not found") - db_post = cast(dict[str, Any], db_post) - await crud_posts.delete(db=db, id=id) return {"message": "Post deleted"} @@ -166,13 +153,9 @@ async def erase_db_post( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) - db_post = await crud_posts.get(db=db, id=id, is_deleted=False, schema_to_select=PostRead) if db_post is None: raise NotFoundException("Post not found") - db_post = cast(dict[str, Any], db_post) - await crud_posts.db_delete(db=db, id=id) return {"message": "Post deleted from the database"} diff --git a/src/app/api/v1/rate_limits.py b/src/app/api/v1/rate_limits.py index 6fac2d9..2831780 100644 --- a/src/app/api/v1/rate_limits.py +++ b/src/app/api/v1/rate_limits.py @@ -1,4 +1,4 @@ -from typing import Annotated, Any, cast +from typing import Annotated, Any from fastapi import APIRouter, Depends, Request from fastcrud import PaginatedListResponse, compute_offset, paginated_response @@ -23,9 +23,6 @@ async def write_rate_limit( if not db_tier: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) - - db_tier = cast(dict[str, Any], db_tier) rate_limit_internal_dict = rate_limit.model_dump() rate_limit_internal_dict["tier_id"] = db_tier["id"] @@ -43,7 +40,7 @@ async def write_rate_limit( if rate_limit_read is None: raise NotFoundException("Created rate limit not found") - return cast(dict[str, Any], rate_limit_read) + return rate_limit_read @router.get("/tier/{tier_name}/rate_limits", response_model=PaginatedListResponse[RateLimitRead]) @@ -58,8 +55,6 @@ async def read_rate_limits( if not db_tier: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) - rate_limits_data = await crud_rate_limits.get_multi( db=db, offset=compute_offset(page, items_per_page), @@ -79,13 +74,11 @@ async def read_rate_limit( if not db_tier: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) - db_rate_limit = await crud_rate_limits.get(db=db, tier_id=db_tier["id"], id=id, schema_to_select=RateLimitRead) if db_rate_limit is None: raise NotFoundException("Rate Limit not found") - return cast(dict[str, Any], db_rate_limit) + return db_rate_limit @router.patch("/tier/{tier_name}/rate_limit/{id}", dependencies=[Depends(get_current_superuser)]) @@ -100,8 +93,6 @@ async def patch_rate_limit( if not db_tier: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) - db_rate_limit = await crud_rate_limits.get(db=db, tier_id=db_tier["id"], id=id, schema_to_select=RateLimitRead) if db_rate_limit is None: raise NotFoundException("Rate Limit not found") @@ -118,8 +109,6 @@ async def erase_rate_limit( if not db_tier: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) - db_rate_limit = await crud_rate_limits.get(db=db, tier_id=db_tier["id"], id=id, schema_to_select=RateLimitRead) if db_rate_limit is None: raise NotFoundException("Rate Limit not found") diff --git a/src/app/api/v1/tiers.py b/src/app/api/v1/tiers.py index 1f676ca..dcdbe1e 100644 --- a/src/app/api/v1/tiers.py +++ b/src/app/api/v1/tiers.py @@ -1,4 +1,4 @@ -from typing import Annotated, Any, cast +from typing import Annotated, Any from fastapi import APIRouter, Depends, Request from fastcrud import PaginatedListResponse, compute_offset, paginated_response @@ -32,7 +32,7 @@ async def write_tier( if tier_read is None: raise NotFoundException("Created tier not found") - return cast(dict[str, Any], tier_read) + return tier_read @router.get("/tiers", response_model=PaginatedListResponse[TierRead]) @@ -51,7 +51,7 @@ async def read_tier(request: Request, name: str, db: Annotated[AsyncSession, Dep if db_tier is None: raise NotFoundException("Tier not found") - return cast(dict[str, Any], db_tier) + return db_tier @router.patch("/tier/{name}", dependencies=[Depends(get_current_superuser)]) diff --git a/src/app/api/v1/users.py b/src/app/api/v1/users.py index 4bbfe95..014a2ce 100644 --- a/src/app/api/v1/users.py +++ b/src/app/api/v1/users.py @@ -1,4 +1,4 @@ -from typing import Annotated, Any, cast +from typing import Annotated, Any from fastapi import APIRouter, Depends, Request from fastcrud import PaginatedListResponse, compute_offset, paginated_response @@ -43,7 +43,7 @@ async def write_user( if user_read is None: raise NotFoundException("Created user not found") - return cast(dict[str, Any], user_read) + return user_read @router.get("/users", response_model=PaginatedListResponse[UserRead]) @@ -74,7 +74,7 @@ async def read_user( if db_user is None: raise NotFoundException("User not found") - return cast(dict[str, Any], db_user) + return db_user @router.patch("/user/{username}") @@ -151,7 +151,6 @@ async def read_user_rate_limits( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) user_dict = dict(db_user) if db_user["tier_id"] is None: user_dict["tier_rate_limits"] = [] @@ -161,7 +160,6 @@ async def read_user_rate_limits( if db_tier is None: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) db_rate_limits = await crud_rate_limits.get_multi(db=db, tier_id=db_tier["id"]) user_dict["tier_rate_limits"] = db_rate_limits["data"] @@ -177,7 +175,6 @@ async def read_user_tier( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) if db_user["tier_id"] is None: return None @@ -185,7 +182,6 @@ async def read_user_tier( if not db_tier: raise NotFoundException("Tier not found") - db_tier = cast(dict[str, Any], db_tier) user_dict = dict(db_user) tier_dict = dict(db_tier) @@ -203,7 +199,6 @@ async def patch_user_tier( if db_user is None: raise NotFoundException("User not found") - db_user = cast(dict[str, Any], db_user) db_tier = await crud_tiers.get(db=db, id=values.tier_id, schema_to_select=TierRead) if db_tier is None: raise NotFoundException("Tier not found") diff --git a/src/app/core/security.py b/src/app/core/security.py index cca070a..d589078 100644 --- a/src/app/core/security.py +++ b/src/app/core/security.py @@ -1,6 +1,6 @@ from datetime import UTC, datetime, timedelta from enum import Enum -from typing import Any, Literal, cast +from typing import Any, Literal import bcrypt from fastapi.security import OAuth2PasswordBearer @@ -45,7 +45,6 @@ async def authenticate_user(username_or_email: str, password: str, db: AsyncSess if not db_user: return False - db_user = cast(dict[str, Any], db_user) if not await verify_password(password, db_user["hashed_password"]): return False diff --git a/uv.lock b/uv.lock index 1a47494..1b8e207 100644 --- a/uv.lock +++ b/uv.lock @@ -433,7 +433,7 @@ requires-dist = [ { name = "crudadmin", specifier = ">=0.4.2" }, { name = "faker", marker = "extra == 'dev'", specifier = ">=26.0.0" }, { name = "fastapi", specifier = ">=0.109.1" }, - { name = "fastcrud", specifier = ">=0.19.0" }, + { name = "fastcrud", specifier = ">=0.19.1" }, { name = "greenlet", specifier = ">=2.0.2" }, { name = "gunicorn", specifier = ">=23.0.0" }, { name = "httptools", specifier = ">=0.6.1" }, @@ -468,7 +468,7 @@ dev = [ [[package]] name = "fastcrud" -version = "0.19.0" +version = "0.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastapi" }, @@ -476,9 +476,9 @@ dependencies = [ { name = "sqlalchemy" }, { name = "sqlalchemy-utils" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/37/38/7c908b08a126647a5e230810338350f5d92b76823ebe4f3e82b20a489518/fastcrud-0.19.0.tar.gz", hash = "sha256:6478a005be6cb39a26958ea1ecf478b953827dd6ecd884a8486d610c7d176355", size = 70345 } +sdist = { url = "https://files.pythonhosted.org/packages/59/ed/e172ad15fb591874a533d7cc46e93785e870b30fd4b36487a0807fbb2cec/fastcrud-0.19.1.tar.gz", hash = "sha256:fb988b912b6dfc6fe0cfcfba658a6a064f9fbb8dd9d3c1d76fc4fe1c36ab525a", size = 70499 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1b/7c/42582f4eb5e54bf4a5e38bfc4cb1466be6c4229e3cc78616b7b135e572f7/fastcrud-0.19.0-py3-none-any.whl", hash = "sha256:67113cdf09617086b1857f388ca9c07375ae432f575e5a420536db813fb2df5a", size = 97529 }, + { url = "https://files.pythonhosted.org/packages/3d/08/0e3ffd9ea3458dea16769e57ae035759bbd72a1b2c957102e36f792a9f40/fastcrud-0.19.1-py3-none-any.whl", hash = "sha256:0171b45e5ef8ca09cb48118a9b72e86f5d371c50bd85260e11c4e62fd180e1e3", size = 97638 }, ] [[package]]