Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ To switch between the 2 methods, stop en remove all containers then build again
- [x] setup database-session + commit in aiohttp-middleware (1 commit per request). in middleware try/catch with rollback in catch. app start open connection, app shutdown close connection
- [x] setup dependency injection in app start so handler doesnt need to get repository from the request + and create new service every request (middleware adds product_service to the request.)
- [x] add test-tooling and unit tests
- [ ] add pagination to /list
- [x] add pagination to /list
- [ ] add custom exceptions (middleware catch Exception, return a fitting response for certain exceptions)
- [ ] use sqlalchamy async queries https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html for better performance
- [ ] setup migrations (use Flyway)
- [ ] input validation
- [ ] Github Actions (linting, testing)
- [x] Github Actions (linting, testing)
- ...
310 changes: 0 additions & 310 deletions mock-products.json

This file was deleted.

7 changes: 3 additions & 4 deletions peterpy/database/models/product.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime, timezone

from sqlalchemy import BigInteger, Column, DateTime, String
from sqlalchemy import BigInteger, Column, String
from sqlalchemy.dialects.mysql import DATETIME

from peterpy.database.models.base import Base

Expand All @@ -12,9 +13,7 @@ class Product(Base):
product_id = Column(String(255), primary_key=True)
name = Column(String(255), nullable=False, unique=True)
price = Column(BigInteger, nullable=False)
date_added = Column(
DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)
)
date_added = Column(DATETIME(fsp=6), default=lambda: datetime.now(timezone.utc))

def __repr__(self) -> str:
return (
Expand Down
12 changes: 6 additions & 6 deletions peterpy/handlers/product_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ async def list_products(request: Request) -> Response:
logging.debug("---------------------------------")
logging.info("List products requested from %s", request.remote)

page = int(request.query.get("page", 1))
limit = int(request.query.get("limit", 20))

# converting the products to a list here
# removes the memory advantage of using a generator
# really using the benefits of a generator would be to use it
# in the json encoder, which would then iterate over the generator
# and stream the response items one by one back to the client

# TODO: investigate how to stream the response item by item back to the client
products = list(product_service.all())
products = list(product_service.all(page, limit))

return json_response(status=200, content={"products": products})

Expand Down Expand Up @@ -91,14 +94,11 @@ async def get_dashboard(request: Request) -> Response:
logging.info("Dashboard requested from %s", request.remote)

products_count = product_service.count()
products = product_service.all()
# products_total_value = sum([product.price for product in products])
# below version is more efficient because it uses a generator expression
products_total_value = sum(product.price for product in products)
products_sum = product_service.sum()

output = {
"products_count": products_count,
"products_total_value": products_total_value,
"products_total_value": products_sum,
}

return json_response(status=200, content={"dashboard": output})
2 changes: 1 addition & 1 deletion peterpy/interfaces/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def find_one(self, obj_id: UUID) -> T:
raise NotImplementedError

@abstractmethod
def all(self) -> Generator[T, None, None]:
def all(self, page: int, limit: int) -> Generator[T, None, None]:
raise NotImplementedError

@abstractmethod
Expand Down
Loading