Skip to content

Commit

Permalink
Merge pull request #26 from PostechSOAT2024Grupo40/fix/responses
Browse files Browse the repository at this point in the history
fix: responses
  • Loading branch information
felixrodrigo19 authored Oct 15, 2024
2 parents ce2be7a + 96a3a6f commit d4554b1
Show file tree
Hide file tree
Showing 24 changed files with 161 additions and 165 deletions.
5 changes: 5 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import sys

import uvicorn
from loguru import logger

from src.api.presentation.http import http # noqa

logger.add(sys.stdout, enqueue=True)

if __name__ == "__main__":
uvicorn.run("src.api.presentation.http:http.app", host="127.0.0.1", port=8000, reload=True)
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ authors = [
]
dependencies = [
"fastapi[standard]==0.115.0",
"loguru==0.7.2",
"psycopg2-binary==2.9.9",
"sqlalchemy==2.0.35",
]
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ idna==3.10
# httpx
jinja2==3.1.4
# via fastapi
loguru==0.7.2
# via ambrosia-serve (pyproject.toml)
markdown-it-py==3.0.0
# via rich
markupsafe==2.1.5
Expand Down
28 changes: 11 additions & 17 deletions src/api/presentation/routes/cart/cart.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import List

from fastapi import APIRouter, HTTPException
from loguru import logger
from pydantic import ValidationError

from src.api.presentation.shared.dtos.create_order_request_dto import CreateOrderRequestDto
Expand All @@ -18,7 +19,8 @@ async def create_order(order_request: CreateOrderRequestDto) -> OrderResponseDto
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {order_request=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.get("/api/v1/orders")
Expand All @@ -28,7 +30,8 @@ async def get_all_orders() -> List[OrderResponseDto]:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception("Server Error")
raise HTTPException(status_code=500, detail=exc.args)


@router.get("/api/v1/order/{id}")
Expand All @@ -38,19 +41,8 @@ async def get_order_by_id(id: str) -> OrderResponseDto:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")


@router.put("/api/v1/order/{id}")
async def update_order(id: str, order_request: CreateOrderRequestDto) -> OrderResponseDto:
try:
order_request_dict = order_request.dict()
return CartController.update_order(order_id=id, request_data=order_request_dict)
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")

logger.exception(f"Server Error | {id=}")
raise HTTPException(status_code=500, detail=exc.args)

@router.put("/api/v1/order/{id}/status")
async def update_order_status(id: str, new_status: str) -> OrderResponseDto:
Expand All @@ -59,7 +51,8 @@ async def update_order_status(id: str, new_status: str) -> OrderResponseDto:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {id=} {new_status=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.delete("/api/v1/order/{id}")
Expand All @@ -69,4 +62,5 @@ async def delete_order(id: str):
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {id=}")
raise HTTPException(status_code=500, detail=exc.args)
18 changes: 12 additions & 6 deletions src/api/presentation/routes/client/client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from fastapi import APIRouter, HTTPException
from loguru import logger
from pydantic import ValidationError

from src.api.presentation.shared.dtos.client_response_dto import ClientResponseDto
Expand All @@ -16,7 +17,8 @@ async def create_user(create_user: CreateUserRequestDTO) -> ClientResponseDto:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {create_user=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.get("/api/v1/users")
Expand All @@ -26,7 +28,8 @@ async def get_users() -> list[ClientResponseDto]:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception("Server Error")
raise HTTPException(status_code=500, detail=exc.args)


@router.get("/api/v1/user/{cpf}")
Expand All @@ -36,17 +39,19 @@ async def get_user_by_cpf(cpf: str) -> ClientResponseDto:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {cpf=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.put("/api/v1/user/")
async def update_user(update_user: CreateUserRequestDTO) -> ClientResponseDto:
try:
return UserController.update_user(update_user)
return UserController.update_user(update_user.model_dump())
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {update_user=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.delete("/api/v1/user/{id}")
Expand All @@ -56,4 +61,5 @@ async def delete_user(id: str) -> bool:
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {id=}")
raise HTTPException(status_code=500, detail=exc.args)
32 changes: 26 additions & 6 deletions src/api/presentation/routes/products/products.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from fastapi import APIRouter, HTTPException
from loguru import logger
from pydantic import ValidationError

from src.api.presentation.shared.dtos.create_product_request_dto import CreateProductRequestDto
from src.api.presentation.shared.dtos.product_response_dto import ProductResponseDto
from src.product.domain_exception import ProductDomainException
from src.product.exceptions import ProductExistsError, ProductNotFoundError
from src.product.product_controller import ProductController

router = APIRouter()
Expand All @@ -15,8 +18,12 @@ async def create_product(product: CreateProductRequestDto) -> ProductResponseDto
return ProductController.create_product(request_data=product_dict)
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except (ProductDomainException, ProductExistsError, ProductNotFoundError) as domain_exc:
logger.exception(f"Server Error | {product=}")
raise HTTPException(status_code=409, detail=domain_exc.args)
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {product=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.get("/api/v1/product/{sku}")
Expand All @@ -25,8 +32,12 @@ async def get_product_by_id(sku: str):
return ProductController.get_product_by_id(sku)
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except (ProductDomainException, ProductExistsError, ProductNotFoundError) as domain_exc:
logger.exception(f"Server Error | {sku=}")
raise HTTPException(status_code=409, detail=domain_exc.args)
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {sku=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.get("/api/v1/products")
Expand All @@ -36,7 +47,8 @@ async def get_all_products():
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception("Server Error")
raise HTTPException(status_code=500, detail=exc.args)


@router.delete("/api/v1/product/{sku}")
Expand All @@ -45,15 +57,23 @@ async def delete_product(sku: str):
return ProductController.delete_product(sku)
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except (ProductDomainException, ProductNotFoundError) as domain_exc:
logger.exception(f"Server Error | {sku=}")
raise HTTPException(status_code=409, detail=domain_exc.args)
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {sku=}")
raise HTTPException(status_code=500, detail=exc.args)


@router.put("/api/v1/product/{sku}")
async def update_product(sku: str, update_product: CreateProductRequestDto):
try:
return ProductController.update_product(sku=sku, request_data=update_product)
return ProductController.update_product(sku=sku, request_data=update_product.model_dump())
except ValidationError as pydantic_exc:
raise HTTPException(status_code=400, detail=pydantic_exc.errors())
except (ProductDomainException, ProductExistsError, ProductNotFoundError) as domain_exc:
logger.exception(f"Server Error | {sku=} {update_product=}")
raise HTTPException(status_code=409, detail=domain_exc.args)
except Exception as exc:
raise HTTPException(status_code=500, detail="Server Error")
logger.exception(f"Server Error | {sku=} {update_product=}")
raise HTTPException(status_code=500, detail=exc.args)
10 changes: 5 additions & 5 deletions src/api/presentation/shared/dtos/client_response_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@


class ClientResponseDto(BaseModel):
id: Optional[str] = None
first_name: Optional[str] = None
last_name: Optional[str] = None
cpf: Optional[str] = None
email: Optional[str] = None
id: Optional[str] = ''
first_name: Optional[str] = ''
last_name: Optional[str] = ''
cpf: Optional[str] = ''
email: Optional[str] = ''
12 changes: 6 additions & 6 deletions src/api/presentation/shared/dtos/create_order_request_dto.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
from typing import Optional

from pydantic import BaseModel

from src.cart.domain.enums.paymentConditions import PaymentConditions
from src.cart.domain.entities.order_product import OrderProduct
from src.api.presentation.shared.dtos.create_product_request_dto import CreateProductRequestDto


class OrderProductDto(BaseModel):
product: CreateProductRequestDto
product_sku: str
quantity: int
observation: str
observation: Optional[str] = ''


class CreateOrderRequestDto(BaseModel):
user_id: str
payment_condition: PaymentConditions
products: list[OrderProductDto]

class Config:
use_enum_values = True

2 changes: 1 addition & 1 deletion src/api/presentation/shared/dtos/order_response_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class OrderProductResponseDto(BaseModel):
product: str
quantity: int
observation: Optional[str] = None
observation: Optional[str] = ''


class OrderResponseDto(BaseModel):
Expand Down
8 changes: 4 additions & 4 deletions src/api/presentation/shared/dtos/product_response_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@


class ProductResponseDto(BaseModel):
id: Optional[str] = None
sku: Optional[str] = None
description: Optional[str] = None
category: Optional[str] = None
id: Optional[str] = ''
sku: Optional[str] = ''
description: Optional[str] = ''
category: Optional[str] = ''
stock: Optional[int] = None
price: Optional[float] = None
5 changes: 3 additions & 2 deletions src/cart/adapters/order_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class OrderTable(Base):
id = Column(String(255), primary_key=True, nullable=False, autoincrement=False)
user_id = Column(String(255), nullable=False)
status = Column(Integer, nullable=False)
payment_condition = Column(Integer, nullable=False)
products = relationship("OrderProductTable", back_populates="order")
payment_condition = Column(String(255), nullable=False)
products = relationship("OrderProductTable", back_populates="order", cascade="all, delete-orphan")
created_at = Column(DateTime, nullable=False, default=now())
updated_at = Column(DateTime, nullable=False, default=now(), onupdate=now())

Expand All @@ -31,6 +31,7 @@ class OrderProductTable(Base):
updated_at = Column(DateTime, nullable=False, default=now(), onupdate=now())

order_id = Column(String(255), ForeignKey("orders.id"), nullable=False)
order = relationship("OrderTable", back_populates="products")

def to_dict(self):
return {column.name: getattr(self, column.name) for column in self.__table__.columns}
10 changes: 7 additions & 3 deletions src/cart/adapters/postgres_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from src.cart.domain.entities.order import Order
from src.cart.domain.entities.order_product import OrderProduct
from src.cart.domain.enums.paymentConditions import PaymentConditions
from src.cart.ports.cart_gateway import ICartGateway
from src.cart.ports.unit_of_work_interface import ICartUnitOfWork

Expand All @@ -24,13 +25,14 @@ def get_order_by_id(self, order_id: str) -> Order:

def create_update_order(self, order: Order) -> Order:
with self.uow:
condition = PaymentConditions(order.payment_condition)
self.uow.repository.insert_update({
'id': order.id,
'user_id': order.user,
'order_status': order.order_status,
'payment_condition': order.payment_condition,
'status': order.order_status.value,
'payment_condition': condition.name,
'products': [{'id': p.id,
'product': p.product, # sku
'product_id': p.product.sku, # sku
'quantity': p.quantity,
'observation': p.observation} for p in order.products]
})
Expand All @@ -43,6 +45,8 @@ def delete_order(self, order_id: str) -> None:
self.uow.commit()

def build_order_entity(self, order):
if not order:
return None
products = [self.build_order_product_entity(p) for p in order['products']]

return Order(_id=order['id'],
Expand Down
23 changes: 12 additions & 11 deletions src/cart/adapters/postgresql_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,20 @@ def filter_by_id(self, order_id: str) -> Dict:
return results[0].to_dict()

def insert_update(self, values: Dict[str, Any]):
stmt_product = insert(OrderProductTable).values(**values['products'])
stmt_product = stmt_product.on_conflict_do_update(
index_elements=[OrderProductTable.id],
set_=values['products']
)
self.session.execute(stmt_product)

stmt = insert(OrderTable).values(**values)
stmt = stmt.on_conflict_do_update(
stmt_order = insert(OrderTable).values({key: values[key] for key in values if key != 'products'})
stmt_order = stmt_order.on_conflict_do_update(
index_elements=[OrderTable.id],
set_=values
set_={key: values[key] for key in values if key != 'id' and key != 'products'}
)
self.session.execute(stmt)
self.session.execute(stmt_order)

for product in values['products']:
stmt_product = insert(OrderProductTable).values(product)
stmt_product = stmt_product.on_conflict_do_update(
index_elements=[OrderProductTable.id],
set_={key: product[key] for key in product if key != 'id'}
)
self.session.execute(stmt_product)

def delete(self, sku: str):
stmt = delete(OrderTable).where(OrderTable.id == sku)
Expand Down
Loading

0 comments on commit d4554b1

Please sign in to comment.