Skip to content

Commit 658e61a

Browse files
committed
use uow in services, flask app
1 parent 833d48b commit 658e61a

File tree

7 files changed

+55
-50
lines changed

7 files changed

+55
-50
lines changed

src/allocation/adapters/orm.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ def start_mappers():
4141
batches,
4242
properties={
4343
"_allocations": relationship(
44-
lines_mapper, secondary=allocations, collection_class=set,
44+
lines_mapper,
45+
secondary=allocations,
46+
collection_class=set,
4547
)
4648
},
4749
)

src/allocation/entrypoints/flask_app.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,16 @@
33
from sqlalchemy import create_engine
44
from sqlalchemy.orm import sessionmaker
55

6-
from allocation import config
76
from allocation.domain import model
8-
from allocation.adapters import orm, repository
9-
from allocation.service_layer import services
7+
from allocation.adapters import orm
8+
from allocation.service_layer import services, unit_of_work
109

11-
orm.start_mappers()
12-
get_session = sessionmaker(bind=create_engine(config.get_postgres_uri()))
1310
app = Flask(__name__)
11+
orm.start_mappers()
1412

1513

1614
@app.route("/add_batch", methods=["POST"])
1715
def add_batch():
18-
session = get_session()
19-
repo = repository.SqlAlchemyRepository(session)
2016
eta = request.json["eta"]
2117
if eta is not None:
2218
eta = datetime.fromisoformat(eta).date()
@@ -25,23 +21,19 @@ def add_batch():
2521
request.json["sku"],
2622
request.json["qty"],
2723
eta,
28-
repo,
29-
session,
24+
unit_of_work.SqlAlchemyUnitOfWork(),
3025
)
3126
return "OK", 201
3227

3328

3429
@app.route("/allocate", methods=["POST"])
3530
def allocate_endpoint():
36-
session = get_session()
37-
repo = repository.SqlAlchemyRepository(session)
3831
try:
3932
batchref = services.allocate(
4033
request.json["orderid"],
4134
request.json["sku"],
4235
request.json["qty"],
43-
repo,
44-
session,
36+
unit_of_work.SqlAlchemyUnitOfWork(),
4537
)
4638
except (model.OutOfStock, services.InvalidSku) as e:
4739
return {"message": str(e)}, 400

src/allocation/service_layer/services.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from allocation.domain import model
66
from allocation.domain.model import OrderLine
7-
from allocation.adapters.repository import AbstractRepository
7+
from allocation.service_layer import unit_of_work
88

99

1010
class InvalidSku(Exception):
@@ -17,20 +17,22 @@ def is_valid_sku(sku, batches):
1717

1818
def add_batch(
1919
ref: str, sku: str, qty: int, eta: Optional[date],
20-
repo: AbstractRepository, session,
21-
) -> None:
22-
repo.add(model.Batch(ref, sku, qty, eta))
23-
session.commit()
20+
uow: unit_of_work.AbstractUnitOfWork,
21+
):
22+
with uow:
23+
uow.batches.add(model.Batch(ref, sku, qty, eta))
24+
uow.commit()
2425

2526

2627
def allocate(
2728
orderid: str, sku: str, qty: int,
28-
repo: AbstractRepository, session,
29+
uow: unit_of_work.AbstractUnitOfWork,
2930
) -> str:
3031
line = OrderLine(orderid, sku, qty)
31-
batches = repo.list()
32-
if not is_valid_sku(line.sku, batches):
33-
raise InvalidSku(f"Invalid sku {line.sku}")
34-
batchref = model.allocate(line, batches)
35-
session.commit()
32+
with uow:
33+
batches = uow.batches.list()
34+
if not is_valid_sku(line.sku, batches):
35+
raise InvalidSku(f"Invalid sku {line.sku}")
36+
batchref = model.allocate(line, batches)
37+
uow.commit()
3638
return batchref

src/allocation/unit_of_work.py renamed to src/allocation/service_layer/unit_of_work.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from sqlalchemy.orm.session import Session
77

88
from allocation import config
9-
from allocation import repository
9+
from allocation.adapters import repository
1010

1111

1212
class AbstractUnitOfWork(abc.ABC):
@@ -27,7 +27,11 @@ def rollback(self):
2727
raise NotImplementedError
2828

2929

30-
DEFAULT_SESSION_FACTORY = sessionmaker(bind=create_engine(config.get_postgres_uri(),))
30+
DEFAULT_SESSION_FACTORY = sessionmaker(
31+
bind=create_engine(
32+
config.get_postgres_uri(),
33+
)
34+
)
3135

3236

3337
class SqlAlchemyUnitOfWork(AbstractUnitOfWork):

src/setup.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from setuptools import setup
22

33
setup(
4-
name="allocation", version="0.1", packages=["allocation"],
4+
name="allocation",
5+
version="0.1",
6+
packages=["allocation"],
57
)

tests/integration/test_uow.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import pytest
2-
from allocation import model
3-
from allocation import unit_of_work
1+
from allocation.domain import model
2+
from allocation.service_layer import unit_of_work
43

54

65
def insert_batch(session, ref, sku, qty, eta):

tests/unit/test_services.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
22
from allocation.adapters import repository
3-
from allocation.service_layer import services
3+
from allocation.service_layer import services, unit_of_work
44

55

66
class FakeRepository(repository.AbstractRepository):
@@ -17,38 +17,42 @@ def list(self):
1717
return list(self._batches)
1818

1919

20-
class FakeSession:
21-
committed = False
20+
class FakeUnitOfWork(unit_of_work.AbstractUnitOfWork):
21+
def __init__(self):
22+
self.batches = FakeRepository([])
23+
self.committed = False
2224

2325
def commit(self):
2426
self.committed = True
2527

28+
def rollback(self):
29+
pass
30+
2631

2732
def test_add_batch():
28-
repo, session = FakeRepository([]), FakeSession()
29-
services.add_batch("b1", "CRUNCHY-ARMCHAIR", 100, None, repo, session)
30-
assert repo.get("b1") is not None
31-
assert session.committed
33+
uow = FakeUnitOfWork()
34+
services.add_batch("b1", "CRUNCHY-ARMCHAIR", 100, None, uow)
35+
assert uow.batches.get("b1") is not None
36+
assert uow.committed
3237

3338

3439
def test_allocate_returns_allocation():
35-
repo, session = FakeRepository([]), FakeSession()
36-
services.add_batch("batch1", "COMPLICATED-LAMP", 100, None, repo, session)
37-
result = services.allocate("o1", "COMPLICATED-LAMP", 10, repo, session)
40+
uow = FakeUnitOfWork()
41+
services.add_batch("batch1", "COMPLICATED-LAMP", 100, None, uow)
42+
result = services.allocate("o1", "COMPLICATED-LAMP", 10, uow)
3843
assert result == "batch1"
3944

4045

4146
def test_allocate_errors_for_invalid_sku():
42-
repo, session = FakeRepository([]), FakeSession()
43-
services.add_batch("b1", "AREALSKU", 100, None, repo, session)
47+
uow = FakeUnitOfWork()
48+
services.add_batch("b1", "AREALSKU", 100, None, uow)
4449

4550
with pytest.raises(services.InvalidSku, match="Invalid sku NONEXISTENTSKU"):
46-
services.allocate("o1", "NONEXISTENTSKU", 10, repo, FakeSession())
51+
services.allocate("o1", "NONEXISTENTSKU", 10, uow)
4752

4853

49-
def test_commits():
50-
repo, session = FakeRepository([]), FakeSession()
51-
session = FakeSession()
52-
services.add_batch("b1", "OMINOUS-MIRROR", 100, None, repo, session)
53-
services.allocate("o1", "OMINOUS-MIRROR", 10, repo, session)
54-
assert session.committed is True
54+
def test_allocate_commits():
55+
uow = FakeUnitOfWork()
56+
services.add_batch("b1", "OMINOUS-MIRROR", 100, None, uow)
57+
services.allocate("o1", "OMINOUS-MIRROR", 10, uow)
58+
assert uow.committed

0 commit comments

Comments
 (0)