From db38b1757eed8a9a13ec3c54e7865993322e564b Mon Sep 17 00:00:00 2001 From: Shounak Dey Date: Sun, 2 Feb 2025 22:20:36 +0530 Subject: [PATCH] Correct typos and apply linting correctly Signed-off-by: Shounak Dey --- README.md | 34 ++++++++++++++-------------- fastapi_ecom/app.py | 2 +- fastapi_ecom/database/__init__.py | 3 +++ fastapi_ecom/database/db_setup.py | 6 ++--- fastapi_ecom/router/business.py | 6 ++++- fastapi_ecom/router/product.py | 29 ++++++++++++++++++++---- pyproject.toml | 6 ++--- tests/product/test_product_delete.py | 10 ++++++-- tests/product/test_product_get.py | 10 ++++++-- tests/product/test_product_put.py | 2 +- 10 files changed, 73 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 25cbba2..d6029b7 100644 --- a/README.md +++ b/README.md @@ -104,16 +104,16 @@ This project serves as a strong foundation for developers to build upon. (venv) $ mv fastapi_ecom/config/config.py.example config.py (venv) $ nano fastapi_ecom/config/config.py ``` - Change the variables as per your requirement - `database` = `` as mentioned while setting up the database container. - `username` = `` as mentioned while setting up the database container. - `password` = `` as mentioned while setting up the database container. - `dtbsbhost` = `` as mentioned while setting up the database container. - `dtbsbport` = `` as mentioned while setting up the database container. - `dtbsdriver` = `postgresql+asyncpg` if async database driver to be used or `postgresql+psycopg2` is sync database driver to be used. - `servhost` = `127.0.0.1` if the service is intended to be accessible only on the same device. - `servport` = `8080` if the service is intended to be accessible on the port number `8080` or `[1-65535]` depending on your choice. - `cgreload` = `True` for use in development environments to which automatically reload the unvicorn service. + Change the variables as per your requirement + `database` = `` as mentioned while setting up the database container. + `username` = `` as mentioned while setting up the database container. + `password` = `` as mentioned while setting up the database container. + `dtbsbhost` = `` as mentioned while setting up the database container. + `dtbsbport` = `` as mentioned while setting up the database container. + `dtbsdriver` = `postgresql+asyncpg` if async database driver to be used or `postgresql+psycopg2` is sync database driver to be used. + `servhost` = `127.0.0.1` if the service is intended to be accessible only on the same device. + `servport` = `8080` if the service is intended to be accessible on the port number `8080` or `[1-65535]` depending on your choice. + `cgreload` = `True` for use in development environments to which automatically reload the uvicorn service. Command ```shell (venv) $ mv fastapi_ecom/migrations/alembic.ini.example fastapi_ecom/migrations/alembic.ini @@ -446,10 +446,10 @@ This project serves as a strong foundation for developers to build upon. 2. Business Route This route contains endpoints for performing CRUD operations on business entity. `create`: Endpoint to create a new business account. No authentication is needed for connecting to this endpoint. - `me`: It is a endpoint to fetch the email of the currently authenticated business. + `me`: It is an endpoint to fetch the email of the currently authenticated business. `search`: Endpoint to fetch a paginated list of businesses from the database. No authentication is needed for connecting to this endpoint. `delete`: Endpoint for an authenticated business to delete its own record. - _Note:_ This endpoint will be depricated in future update with the implementation of archiving. + _Note:_ This endpoint will be deprecated in future update with the implementation of archiving. `update`: Endpoint for an authenticated business to update its own record. ![](https://raw.githubusercontent.com/sdglitched/FastAPI-eCom/main/docs/imgs/business_enpt.png) 3. Product Route @@ -460,13 +460,13 @@ This project serves as a strong foundation for developers to build upon. `search/internal`: Endpoint fetches a paginated list of products associated with the authenticated business. `search/uuid`: Endpoint fetches a specific product by its UUID (Product ID) associated with the authenticated business. `delete/uuid`: Endpoint to delete a product by its UUID associated for an authenticated business. - _Note:_ This endpoint will be depricated in future update with the implementation of archiving. + _Note:_ This endpoint will be deprecated in future update with the implementation of archiving. `update/uuid`: Endpoint to update a product by its UUID associated for an authenticated business. ![](https://raw.githubusercontent.com/sdglitched/FastAPI-eCom/main/docs/imgs/product_enpt.png) 4. Customer Route This route contains endpoints for performing CRUD operations on customer entity. `create`: Endpoint to create a new customer account. No authentication is needed for connecting to this endpoint. - `me`: It is a endpoint to fetch the email of the currently authenticated customer. + `me`: It is an endpoint to fetch the email of the currently authenticated customer. `search`: Endpoint to fetch a paginated list of customers from the database. No authentication is needed for connecting to this endpoint. `delete`: Endpoint for an authenticated customer to delete its own record. `update`: Endpoint for an authenticated customer to update its own record. @@ -476,10 +476,10 @@ This project serves as a strong foundation for developers to build upon. `create`: Endpoint to place an order by the authenticated customer. `search`: Endpoint fetches a paginated list of orders and its details associated with the authenticated customer. `search/internal`: Endpoint fetches a paginated list of orders and its details. - _Note:_ This endpoint is ment to be used by an admin account which will created in future update. Currently no authentication is needed for connecting to this endpoint. + _Note:_ This endpoint is ment to be used by an admin account which will created in future update. Currently, no authentication is needed for connecting to this endpoint. `search/uuid`: Endpoint fetches a specific order and its details by its UUID associated with the authenticated customer. - `delete/uuid`: Endpoint to delete a order by its UUID associated for an authenticated customer. - _Note:_ This endpoint will be depricated in future update with the implementation of archiving. + `delete/uuid`: Endpoint to delete an order by its UUID associated for an authenticated customer. + _Note:_ This endpoint will be deprecated in future update with the implementation of archiving. ![](https://raw.githubusercontent.com/sdglitched/FastAPI-eCom/main/docs/imgs/order_enpt.png) ## Future Roadmap diff --git a/fastapi_ecom/app.py b/fastapi_ecom/app.py index d64ad2e..8cf6870 100644 --- a/fastapi_ecom/app.py +++ b/fastapi_ecom/app.py @@ -10,7 +10,7 @@ tags_metadata = [ {"name": "business", "description": "Operations on businesses"}, {"name": "product", "description": "Operations on products"}, - {"name": "customer", "description": "Operations on customeres"}, + {"name": "customer", "description": "Operations on customers"}, {"name": "order", "description": "Operations on orders"} ] diff --git a/fastapi_ecom/database/__init__.py b/fastapi_ecom/database/__init__.py index de7b112..81693e3 100644 --- a/fastapi_ecom/database/__init__.py +++ b/fastapi_ecom/database/__init__.py @@ -10,6 +10,9 @@ # Base class for ORM models, to be used with SQLAlchemy's declarative system. baseobjc = declarative_base() +# Path of alembic configuration file +alempath = str(Path(str(Path(str(Path(__file__).parent.resolve().parent.resolve()),"migrations").resolve()),"alembic.ini").resolve()) + # Migration path for alembic configuration migrpath = str(Path(str(Path(__file__).parent.resolve().parent.resolve()),"migrations").resolve()) diff --git a/fastapi_ecom/database/db_setup.py b/fastapi_ecom/database/db_setup.py index 52fda19..f60acf2 100644 --- a/fastapi_ecom/database/db_setup.py +++ b/fastapi_ecom/database/db_setup.py @@ -1,10 +1,10 @@ -from pathlib import Path from typing import AsyncGenerator from alembic import command, config from sqlalchemy.ext.asyncio import AsyncSession -from fastapi_ecom.database import ( #noqa: F401 +from fastapi_ecom.database import ( # noqa: F401 + alempath, baseobjc, get_async_session, get_database_url, @@ -28,7 +28,7 @@ def make_database() -> None: baseobjc.metadata.create_all(bind=sync_engine) # Set up Alembic configuration for migration management. - alembic_config = config.Config(str(Path(str(Path(str(Path(__file__).parent.resolve().parent.resolve()),"migrations").resolve()),"alembic.ini").resolve())) + alembic_config = config.Config(alempath) alembic_config.set_main_option("script_location", migrpath) alembic_config.set_main_option("sqlalchemy.url", get_database_url().render_as_string(hide_password=False)) diff --git a/fastapi_ecom/router/business.py b/fastapi_ecom/router/business.py index 7483595..ffa9b89 100644 --- a/fastapi_ecom/router/business.py +++ b/fastapi_ecom/router/business.py @@ -153,7 +153,11 @@ async def delete_business(db: AsyncSession = Depends(get_db), business_auth = De } @router.put("/update/me", status_code=status.HTTP_202_ACCEPTED, response_model=BusinessResult, tags=["business"]) -async def update_business(business: BusinessUpdate, db: AsyncSession = Depends(get_db), business_auth = Depends(verify_business_cred)) -> BusinessResult: +async def update_business( + business: BusinessUpdate, + db: AsyncSession = Depends(get_db), + business_auth = Depends(verify_business_cred) +) -> BusinessResult: """ Endpoint for an authenticated business to update its own record. diff --git a/fastapi_ecom/router/product.py b/fastapi_ecom/router/product.py index a552b01..3464cfa 100644 --- a/fastapi_ecom/router/product.py +++ b/fastapi_ecom/router/product.py @@ -24,7 +24,11 @@ router = APIRouter(prefix="/product") @router.post("/create", status_code=status.HTTP_201_CREATED, response_model=ProductResultInternal, tags=["product"]) -async def add_product(product: ProductCreate, db: AsyncSession = Depends(get_db), business_auth = Depends(verify_business_cred)) -> ProductResultInternal: +async def add_product( + product: ProductCreate, + db: AsyncSession = Depends(get_db), + business_auth = Depends(verify_business_cred) +) -> ProductResultInternal: """ Endpoint to add a new product by currently authenticated business. @@ -121,7 +125,9 @@ async def get_product_by_text( :raises HTTPException: If no matching products exists in the database, it raises 404 Not Found. """ - query = select(Product).where(or_(Product.name.ilike(f"%{text}%"), Product.description.ilike(f"%{text}%"))).options(selectinload("*")).offset(skip).limit(limit) + query = select(Product).where( + or_(Product.name.ilike(f"%{text}%"), Product.description.ilike(f"%{text}%")) + ).options(selectinload("*")).offset(skip).limit(limit) result = await db.execute(query) products = result.scalars().all() if not products: @@ -169,7 +175,11 @@ async def get_products_internal( } @router.get("/search/uuid/{product_id}", status_code=status.HTTP_200_OK, response_model=ProductResultInternal, tags=["product"]) -async def get_product_by_uuid(product_id: str, db: AsyncSession = Depends(get_db), business_auth = Depends(verify_business_cred)) -> ProductResultInternal: +async def get_product_by_uuid( + product_id: str, + db: AsyncSession = Depends(get_db), + business_auth = Depends(verify_business_cred) +) -> ProductResultInternal: """ Endpoint fetches a specific product by its UUID associated with the authenticated business. @@ -198,7 +208,11 @@ async def get_product_by_uuid(product_id: str, db: AsyncSession = Depends(get_db } @router.delete("/delete/uuid/{product_id}", status_code=status.HTTP_202_ACCEPTED, response_model=ProductResultInternal, tags=["product"]) -async def delete_product(product_id: str, db: AsyncSession = Depends(get_db), business_auth = Depends(verify_business_cred)) -> ProductResultInternal: +async def delete_product( + product_id: str, + db: AsyncSession = Depends(get_db), + business_auth = Depends(verify_business_cred) +) -> ProductResultInternal: """ Endpoint to delete a product by its UUID associated for an authenticated business. @@ -242,7 +256,12 @@ async def delete_product(product_id: str, db: AsyncSession = Depends(get_db), bu } @router.put("/update/uuid/{product_id}", status_code=status.HTTP_202_ACCEPTED, response_model=ProductResultInternal, tags=["product"]) -async def update_product(product_id: str, product: ProductUpdate, db: AsyncSession = Depends(get_db), business_auth = Depends(verify_business_cred)) -> ProductResultInternal: +async def update_product( + product_id: str, + product: ProductUpdate, + db: AsyncSession = Depends(get_db), + business_auth = Depends(verify_business_cred) +) -> ProductResultInternal: """ Endpoint to update a product by its UUID associated for an authenticated business. diff --git a/pyproject.toml b/pyproject.toml index 1fe030d..f5062d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,15 +27,15 @@ aiosqlite = "^0.20.0" pytest-mock = "^3.14.0" [tool.ruff] -line-length = 100 +line-length = 150 fix = true [tool.ruff.lint] select = ["E", "F", "W", "I", "S", "B", "UP"] [tool.ruff.lint.per-file-ignores] -"fastapi_ecom/*" = ["E501", "B008"] -"tests/*" = ["S101", "S106", "E501"] +"fastapi_ecom/*" = ["B008"] +"tests/*" = ["S101", "S106",] [tool.pytest.ini_options] asyncio_mode = "auto" diff --git a/tests/product/test_product_delete.py b/tests/product/test_product_delete.py index f8e01ca..a2a5955 100644 --- a/tests/product/test_product_delete.py +++ b/tests/product/test_product_delete.py @@ -8,8 +8,14 @@ @pytest.mark.parametrize( "business_id, product_id, present", [ - pytest.param("5c1c48fb", "d5cf6983", True, id="PRODUCT DELETE Endpoint - Deletes the specific product of currently authenticated business"), - pytest.param("5c1c48fb", "d76a11f2", False, id="PRODUCT DELETE Endpoint - Fails to find the specific product of currently authenticated business"), + pytest.param( + "5c1c48fb", "d5cf6983", True, + id="PRODUCT DELETE Endpoint - Deletes the specific product of currently authenticated business" + ), + pytest.param( + "5c1c48fb", "d76a11f2", False, + id="PRODUCT DELETE Endpoint - Fails to find the specific product of currently authenticated business" + ), ] ) async def test_delete_product( diff --git a/tests/product/test_product_get.py b/tests/product/test_product_get.py index d0963dc..c65659d 100644 --- a/tests/product/test_product_get.py +++ b/tests/product/test_product_get.py @@ -229,8 +229,14 @@ async def test_get_products_internal( @pytest.mark.parametrize( "business_id, product_id, present", [ - pytest.param("d76a11f2", "3250fcbe", True, id="PRODUCT GET Endpoint - Fetch specific product by its UUID which is associated with the authenticated business"), - pytest.param("d76a11f2", "xxxxyyyy", False, id="PRODUCT GET Endpoint - Fail to fetch specific product by its UUID which is associated with the authenticated business") + pytest.param( + "d76a11f2", "3250fcbe", True, + id="PRODUCT GET Endpoint - Fetch specific product by its UUID which is associated with the authenticated business" + ), + pytest.param( + "d76a11f2", "xxxxyyyy", False, + id="PRODUCT GET Endpoint - Fail to fetch specific product by its UUID which is associated with the authenticated business" + ) ] ) async def test_get_product_by_uuid( diff --git a/tests/product/test_product_put.py b/tests/product/test_product_put.py index 3a90e8d..78fe90d 100644 --- a/tests/product/test_product_put.py +++ b/tests/product/test_product_put.py @@ -15,7 +15,7 @@ "name": "Updated Test Product", "description": "Updated Fifth Test Product", "category": "updated test", - "mfg_date": datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None).isoformat(),#"1900-01-01 00:00:00+00:00", + "mfg_date": datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None).isoformat(), "exp_date": datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0, tzinfo=None).isoformat(), "price": 1950.05 },