diff --git a/pyproject.toml b/pyproject.toml index 7e82506..67707be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [project] name = "fastapi-boilerplate" version = "0.1.0" -description = "A fully Async FastAPI boilerplate using SQLAlchemy and Pydantic 2" -authors = [{ name = "Igor Magalhaes", email = "igor.magalhaes.r@gmail.com" }] +description = "Batteries-included FastAPI starter with production-ready defaults, optional modules, and clear docs." +authors = [{ name = "Benav Labs", email = "contact@benav.io" }] license = { text = "MIT" } readme = "README.md" requires-python = ">=3.11, <4" @@ -28,7 +28,7 @@ dependencies = [ "arq>=0.25.0", "bcrypt>=4.1.1", "psycopg2-binary>=2.9.9", - "fastcrud>=0.19.1", + "fastcrud>=0.19.2", "crudadmin>=0.4.2", "gunicorn>=23.0.0", "ruff>=0.11.13", diff --git a/src/app/api/v1/posts.py b/src/app/api/v1/posts.py index 95e39aa..493fcb0 100644 --- a/src/app/api/v1/posts.py +++ b/src/app/api/v1/posts.py @@ -35,16 +35,12 @@ async def write_post( post_internal_dict["created_by_user_id"] = db_user["id"] post_internal = PostCreateInternal(**post_internal_dict) - created_post = await crud_posts.create(db=db, object=post_internal) + created_post = await crud_posts.create(db=db, object=post_internal, schema_to_select=PostRead) if created_post is None: raise NotFoundException("Failed to create post") - post_read = await crud_posts.get(db=db, id=created_post["id"], schema_to_select=PostRead) - if post_read is None: - raise NotFoundException("Created post not found") - - return post_read + return created_post @router.get("/{username}/posts", response_model=PaginatedListResponse[PostRead]) diff --git a/src/app/api/v1/rate_limits.py b/src/app/api/v1/rate_limits.py index 2831780..eec6f4b 100644 --- a/src/app/api/v1/rate_limits.py +++ b/src/app/api/v1/rate_limits.py @@ -31,16 +31,14 @@ async def write_rate_limit( raise DuplicateValueException("Rate Limit Name not available") rate_limit_internal = RateLimitCreateInternal(**rate_limit_internal_dict) - created_rate_limit = await crud_rate_limits.create(db=db, object=rate_limit_internal) + created_rate_limit = await crud_rate_limits.create( + db=db, object=rate_limit_internal, schema_to_select=RateLimitRead + ) if created_rate_limit is None: raise NotFoundException("Failed to create rate limit") - rate_limit_read = await crud_rate_limits.get(db=db, id=created_rate_limit["id"], schema_to_select=RateLimitRead) - if rate_limit_read is None: - raise NotFoundException("Created rate limit not found") - - return rate_limit_read + return created_rate_limit @router.get("/tier/{tier_name}/rate_limits", response_model=PaginatedListResponse[RateLimitRead]) diff --git a/src/app/api/v1/tiers.py b/src/app/api/v1/tiers.py index dcdbe1e..03ca6f8 100644 --- a/src/app/api/v1/tiers.py +++ b/src/app/api/v1/tiers.py @@ -23,16 +23,12 @@ async def write_tier( raise DuplicateValueException("Tier Name not available") tier_internal = TierCreateInternal(**tier_internal_dict) - created_tier = await crud_tiers.create(db=db, object=tier_internal) + created_tier = await crud_tiers.create(db=db, object=tier_internal, schema_to_select=TierRead) if created_tier is None: raise NotFoundException("Failed to create tier") - tier_read = await crud_tiers.get(db=db, id=created_tier["id"], schema_to_select=TierRead) - if tier_read is None: - raise NotFoundException("Created tier not found") - - return tier_read + return created_tier @router.get("/tiers", response_model=PaginatedListResponse[TierRead]) diff --git a/src/app/api/v1/users.py b/src/app/api/v1/users.py index 014a2ce..60264cc 100644 --- a/src/app/api/v1/users.py +++ b/src/app/api/v1/users.py @@ -34,16 +34,12 @@ async def write_user( del user_internal_dict["password"] user_internal = UserCreateInternal(**user_internal_dict) - created_user = await crud_users.create(db=db, object=user_internal) + created_user = await crud_users.create(db=db, object=user_internal, schema_to_select=UserRead) if created_user is None: raise NotFoundException("Failed to create user") - user_read = await crud_users.get(db=db, id=created_user["id"], schema_to_select=UserRead) - if user_read is None: - raise NotFoundException("Created user not found") - - return user_read + return created_user @router.get("/users", response_model=PaginatedListResponse[UserRead]) diff --git a/tests/test_user.py b/tests/test_user.py index 9d1d7a5..0cddbea 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -20,8 +20,7 @@ async def test_create_user_success(self, mock_db, sample_user_data, sample_user_ with patch("src.app.api.v1.users.crud_users") as mock_crud: # Mock that email and username don't exist mock_crud.exists = AsyncMock(side_effect=[False, False]) # email, then username - mock_crud.create = AsyncMock(return_value={"id": 1}) - mock_crud.get = AsyncMock(return_value=sample_user_read.model_dump()) + mock_crud.create = AsyncMock(return_value=sample_user_read.model_dump()) with patch("src.app.api.v1.users.get_password_hash") as mock_hash: mock_hash.return_value = "hashed_password" diff --git a/uv.lock b/uv.lock index 1b8e207..6b2f7be 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.1" }, + { name = "fastcrud", specifier = ">=0.19.2" }, { 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.1" +version = "0.19.2" 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/59/ed/e172ad15fb591874a533d7cc46e93785e870b30fd4b36487a0807fbb2cec/fastcrud-0.19.1.tar.gz", hash = "sha256:fb988b912b6dfc6fe0cfcfba658a6a064f9fbb8dd9d3c1d76fc4fe1c36ab525a", size = 70499 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/ae/1fc88455e8e399aff19e591423a948cfcdb712a5974fb8d0cedb31412dae/fastcrud-0.19.2.tar.gz", hash = "sha256:d048177cfd6fc1209a36ee71d9790bc7fc16a2c5d856ff783273699533b43bb3", size = 70870 } wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/08/0e3ffd9ea3458dea16769e57ae035759bbd72a1b2c957102e36f792a9f40/fastcrud-0.19.1-py3-none-any.whl", hash = "sha256:0171b45e5ef8ca09cb48118a9b72e86f5d371c50bd85260e11c4e62fd180e1e3", size = 97638 }, + { url = "https://files.pythonhosted.org/packages/20/6e/f038ca92fe680ad31cee176c61a5536ddbf31f1bbf3923975fd221917abc/fastcrud-0.19.2-py3-none-any.whl", hash = "sha256:1562a905f92196e485d2df2f6ea34f0408702bf41c6cad3a89a1fedf08a4f4d9", size = 98032 }, ] [[package]]