Skip to content

Commit 21facc3

Browse files
committed
feat(presentation): add fastapi
1 parent 7b6cd51 commit 21facc3

23 files changed

+516
-23
lines changed

pyproject.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ indent-width = 4
6161
[tool.ruff.lint]
6262
select = [
6363
"ANN", "F", "W", "E", "B", "C90", "N", "UP", "YTT", "ASYNC", "PL", "RUF",
64-
"Q", "RET", "SLF", "SLOT", "SIM", "TID252", "TCH", "ARG", "PTH", "ERA", "TRY",
65-
"PERF", "INP", "I", "S", "FAST", "TID", "TCH", "INT"
64+
"Q", "RET", "SLF", "SLOT", "SIM", "TID252", "TCH", "ARG", "PTH", "ERA",
65+
"TRY", "PERF", "INP", "I", "S", "FAST", "TID", "TCH", "INT"
66+
]
67+
ignore = [
68+
"N818", "RUF009", "UP018", "PLR6301", "PLR0913", "PLW0108", "TC006",
69+
"S101", "TC003", "TC002"
6670
]
67-
ignore = ["N818", "RUF009", "UP018", "PLR6301", "PLR0913", "PLW0108", "TC006", "S101"]
6871

6972
[tool.ruff.lint.isort]
7073
lines-after-imports = 2

src/tgdb/entities/transaction.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from collections.abc import Iterable, Sequence
2-
from dataclasses import dataclass
2+
from dataclasses import dataclass, field
33
from uuid import UUID
44

55
from tgdb.entities.logic_time import LogicTime
@@ -23,6 +23,10 @@ class TransactionConflict:
2323
marks: frozenset[Mark]
2424

2525

26+
@dataclass(frozen=True)
27+
class NoTransaction: ...
28+
29+
2630
@dataclass(frozen=True)
2731
class TransactionOkCommit:
2832
transaction_id: UUID
@@ -32,7 +36,7 @@ class TransactionOkCommit:
3236
@dataclass(frozen=True)
3337
class TransactionFailedCommit:
3438
transaction_id: UUID
35-
conflict: TransactionConflict | None
39+
reason: TransactionConflict | NoTransaction = field(kw_only=True)
3640

3741

3842
type TransactionCommit = TransactionOkCommit | TransactionFailedCommit
@@ -71,7 +75,7 @@ def commit(self) -> TransactionCommit:
7175

7276
if conflict is not None:
7377
self._die()
74-
return TransactionFailedCommit(self.id, conflict)
78+
return TransactionFailedCommit(self.id, reason=conflict)
7579

7680
for transaction in self._concurrent_transactions:
7781
transaction._transactions_with_possible_conflict.append(self)

src/tgdb/entities/transaction_horizon.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
StartOperator,
1313
)
1414
from tgdb.entities.transaction import (
15+
NoTransaction,
1516
Transaction,
1617
TransactionCommit,
1718
TransactionFailedCommit,
@@ -114,7 +115,7 @@ def _add_operator(self, operator: Operator) -> TransactionCommit | None:
114115

115116
case CommitOperator(), None:
116117
return TransactionFailedCommit(
117-
operator.transaction_id, conflict=None
118+
operator.transaction_id, reason=NoTransaction()
118119
)
119120

120121
case _:

src/tgdb/infrastructure/adapters/operator_serialization.py

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/tgdb/presentation/__init__.py

Whitespace-only changes.

src/tgdb/presentation/adapters/__init__.py

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from collections.abc import Sequence
2+
from uuid import UUID
3+
4+
from tgdb.application.ports.notification import Notification
5+
from tgdb.entities.transaction import TransactionCommit
6+
from tgdb.presentation.async_map import AsyncMap
7+
8+
9+
class TransactionCommitListNotificationToAsyncMap(
10+
Notification[Sequence[TransactionCommit]]
11+
):
12+
_map: AsyncMap[UUID, TransactionCommit]
13+
14+
async def send(self, commits: Sequence[TransactionCommit], /) -> None:
15+
for commit in commits:
16+
self._map[commit.transaction_id] = commit
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from dataclasses import dataclass
2+
3+
from tgdb.application.ports.operator_serialization import OperatorSerialization
4+
from tgdb.entities.operator import Operator
5+
from tgdb.presentation.fastapi.schemas.entity import EntitySchema
6+
7+
8+
@dataclass(frozen=True)
9+
class OperatorSerializationToOperator(OperatorSerialization[Operator | None]):
10+
async def deserialized(self, operator: Operator | None) -> Operator | None:
11+
return operator
12+
13+
14+
@dataclass(frozen=True)
15+
class OperatorSerializationToEntitySchema[OperatorT: Operator](
16+
OperatorSerialization[EntitySchema[OperatorT]]
17+
):
18+
async def deserialized(self, schema: EntitySchema[OperatorT]) -> OperatorT:
19+
return schema.entity()

src/tgdb/presentation/async_map.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from dataclasses import dataclass, field
2+
3+
from tgdb.presentation.async_result import AsyncResult
4+
5+
6+
@dataclass(frozen=True, unsafe_hash=False)
7+
class AsyncMap[KeyT, ValueT]:
8+
_map: dict[KeyT, AsyncResult[ValueT]] = field(
9+
init=False, default_factory=dict
10+
)
11+
12+
def __getitem__(self, key: KeyT) -> AsyncResult[ValueT]:
13+
if key in self._map:
14+
return self._map[key]
15+
16+
result = AsyncResult[ValueT]()
17+
self._map[key] = result
18+
19+
return result
20+
21+
def __setitem__(self, key: KeyT, value: ValueT) -> None:
22+
if key not in self._map:
23+
return
24+
25+
result = self._map[key]
26+
result.set(value)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from asyncio import Event
2+
from collections.abc import Awaitable, Generator
3+
from dataclasses import dataclass, field
4+
from typing import Any, cast
5+
6+
7+
@dataclass
8+
class AsyncResult[ValueT](Awaitable[ValueT]):
9+
_value: ValueT | None = field(init=False, default=None)
10+
_is_value_set: Event = field(init=False, default_factory=Event)
11+
12+
def set(self, value: ValueT) -> None:
13+
self._value = value
14+
self._is_value_set.set()
15+
16+
def __await__(self) -> Generator[Any, Any, ValueT]:
17+
return self._get().__await__()
18+
19+
async def _get(self) -> ValueT:
20+
await self._is_value_set.wait()
21+
return cast(ValueT, self._value)

0 commit comments

Comments
 (0)