Skip to content

Commit

Permalink
rework cli app example
Browse files Browse the repository at this point in the history
  • Loading branch information
pgorecki committed Jul 6, 2023
1 parent 51b4553 commit 5cdfde8
Showing 1 changed file with 39 additions and 85 deletions.
124 changes: 39 additions & 85 deletions src/cli/__main__.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import copy
import uuid

from sqlalchemy.orm import Session

from config.container import Container
from config.container import TopLevelContainer
from modules.catalog.application.command import CreateListingDraftCommand
from modules.catalog.application.query import GetAllListings
from modules.catalog.domain.repositories import ListingRepository
from modules.catalog.infrastructure.listing_repository import Base
from seedwork.domain.value_objects import Money
from seedwork.infrastructure.logging import LoggerFactory, logger
from seedwork.infrastructure.request_context import request_context

# a sample command line script to print all listings
# run with "cd src && python -m cli"

# configure logger prior to first usage
LoggerFactory.configure(logger_name="cli")

container = Container()
container = TopLevelContainer()
container.config.from_dict(
dict(
# DATABASE_URL="sqlite+pysqlite:///:memory:",
Expand All @@ -24,85 +24,39 @@
)
)

engine = container.db().engine()
# let's create the database schema
engine = container.db_engine()
Base.metadata.create_all(engine)

# let's create a new application instance
app = container.application()


# let's query the listings, this method implicitly creates a transaction context and then executes a query
# see `get_all_listings` query handler in `src/modules/catalog/application/query/get_all_listings.py`
query_result = app.execute_query(GetAllListings())

# now let's print the listings
listings = query_result.payload
print("Listings:")
for listing in listings:
print(f"{listing['id']} - {listing['title']}")

# now we are explicitly creating a transaction context, this time we want to execute a command
with app.transaction_context() as ctx:
# see `create_listing_draft` command handler in `src/modules/catalog/application/command/create_listing_draft.py`
ctx.execute_command(
CreateListingDraftCommand(
listing_id=uuid.uuid4(),
title="First listing",
description="...",
ask_price=Money(100),
seller_id=uuid.UUID(int=1),
)
)

from seedwork.spike.test_scratch import (
ActivateUserCommand,
Application,
CommandResult,
DependencyProvider,
TransactionContext,
)


class CustomDependencyProvider(DependencyProvider):
def __init__(self, ioc_container):
self.ioc_container = ioc_container


provider = CustomDependencyProvider(container)
app = Application(provider)


@app.on_enter_transaction_context
def on_enter_transaction_context(context: TransactionContext):
db_session = Session(engine)
correlation_id = uuid.uuid4()
context.dependency_provider = copy.deepcopy(app.dependency_provider)
context.dependency_provider["correlation_id"] = correlation_id
context.dependency_provider["db_session"] = db_session


@app.on_exit_transaction_context
def on_exit_transaction_context(context: TransactionContext, exc_type, exc_val, exc_tb):
db_session = context.dependency_provider["db_session"]
if exc_val is None:
db_session.commit()
else:
db_session.rollback()
context.dependency_provider["db_session"].close()


@app.transaction_middleware
def logging_middleware(next: callable, context: TransactionContext, task):
correlation_id = context.dependency_provider["correlation_id"]
request_context.correlation_id.set(correlation_id)
logger.info(f"transaction started for {task}")
result = next()
logger.info(f"transaction finished with {result}")
return result


@app.transaction_middleware
def sql_alchemy_session_middleware(next: callable, context: TransactionContext, task):
db_session = context.dependency_provider["db_session"]
logger.debug(f"session {db_session} started")
try:
result = next()
db_session.commit()
logger.debug(f"session {db_session} committed")
return result
except:
db_session.rollback()
logger.debug(f"session {db_session} rolled back")
finally:
db_session.close()


@app.command_handler(ActivateUserCommand)
def activate_user(
command: ActivateUserCommand, user_repository, db_session
) -> CommandResult:
logger.info(f"activate_user {db_session} {user_repository}")
try:
user = user_repository.get_by_id(command.user_id)
except:
user = None
return CommandResult(user)


with app.transaction_context(correlation_id="foo") as ctx:
ctx.execute_command(ActivateUserCommand(user_id=uuid.UUID(int=1)))
ctx.execute_command(ActivateUserCommand(user_id=uuid.UUID(int=2)))
# use transaction context to acccess any dependency (i.e a repository, a service, etc.)
with app.transaction_context() as ctx:
listing_repository = ctx.get_service(ListingRepository)
listing_count = listing_repository.count()
logger.info(f"There are {listing_count} listings in the database")

0 comments on commit 5cdfde8

Please sign in to comment.