Skip to content

Commit 3e7aaf2

Browse files
authored
Merge pull request #3 from t10d/dev
Base DDD modeling (pre-release v0.3.0)
2 parents d93695a + 4b763d3 commit 3e7aaf2

73 files changed

Lines changed: 2204 additions & 42 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Used by "time.generate_now()". Follow the TZ Database format, for details,
2+
# see: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
3+
TIMEZONE_REGION=America/Sao_Paulo
4+
5+
# If active, shows detailed error information, else shows only user friendly
6+
# codes.
7+
DEBUG=False
8+
9+
# The connection URL to the database.
10+
DATABASE_URL = "postgresql://user:password@localhost:5432/database"
11+
12+
# The credentials to connect to Redis message broker.
13+
REDIS_HOST = "127.0.0.1"
14+
REDIS_PORT = "6379"
15+
REDIS_PASSWORD = ""

.github/pull_request_template.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#### 📝 Description
2+
3+
Write a short paragraph explaining the reasons for this PR.
4+
5+
#### 🛠️ Changes
6+
7+
(OPTIONAL) You can make a short list describing the changes, if possible (and if you want) referencing the id's of the related commits.
8+
9+
#### ⚠️ Notes
10+
11+
(OPTIONAL) This section is especially useful in cases where you want to describe a more detailed view of any changes described or not in the previous section.

.github/workflows/release.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# This workflow will upload a Python Package using Twine when a release is created
2+
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3+
4+
name: Upload Python Package
5+
6+
on:
7+
release:
8+
types: [published]
9+
10+
jobs:
11+
deploy:
12+
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
- name: Set up Python
18+
uses: actions/setup-python@v2
19+
with:
20+
python-version: '3.9'
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install build
25+
- name: Build package
26+
run: python -m build
27+
- name: Publish package
28+
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
29+
with:
30+
user: __token__
31+
password: ${{ secrets.PYPI_API_TOKEN }}

.github/workflows/test.yml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# This workflow will run tests against a Postgres and Redis database on Ubuntu
2+
# For more information see: https://docs.github.com/en/actions/using-containerized-services/creating-postgresql-service-containers
3+
4+
name: Run Test Suite
5+
6+
on:
7+
pull_request:
8+
types: [ opened, synchronize, edited ]
9+
branches:
10+
- main
11+
- dev
12+
13+
jobs:
14+
tests:
15+
runs-on: ubuntu-latest
16+
17+
services:
18+
postgres:
19+
image: postgres
20+
env:
21+
POSTGRES_USER: user
22+
POSTGRES_PASSWORD: password
23+
POSTGRES_DB: database
24+
ports: [ "5432:5432" ]
25+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
26+
27+
redis:
28+
image: redis
29+
env:
30+
REDIS_HOST: 127.0.0.1
31+
REDIS_PORT: 6379
32+
ports: [ "6379:6379" ]
33+
options: >-
34+
--health-cmd "redis-cli ping"
35+
--health-interval 10s
36+
--health-timeout 5s
37+
--health-retries 5
38+
39+
steps:
40+
- uses: actions/checkout@v2
41+
- name: Setup Python
42+
uses: actions/setup-python@v1
43+
with:
44+
python-version: "3.9"
45+
- name: Cache pip
46+
uses: actions/cache@v1
47+
with:
48+
path: ~/.cache/pip # This path is specific to Ubuntu
49+
# Look to see if there is a cache hit for the corresponding requirements file
50+
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.dev.txt') }}
51+
restore-keys: |
52+
${{ runner.os }}-pip-
53+
${{ runner.os }}-
54+
- name: Install dependencies
55+
run: pip install -r requirements.dev.txt
56+
57+
- name: Linting checks
58+
run: make black flake8 isort pydocstyle
59+
60+
- name: Typing checks
61+
run: make mypy
62+
63+
- name: Prepare test database
64+
env:
65+
PYTHONPATH: .
66+
run: |
67+
cd tests/poc/
68+
alembic revision --autogenerate
69+
alembic -x data=true -x test=true upgrade head
70+
71+
- name: Unit Tests
72+
run: |
73+
pytest tests/unit --color=yes --showlocals -v
74+
75+
- name: Integration Tests
76+
run: |
77+
pytest tests/integration --color=yes --showlocals -v

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,6 @@ Thumbs.db
139139
# IDE
140140
.idea/
141141
.vscode/
142+
143+
# Don't commit the alembic revision, it's part of test generate them.
144+
tests/poc/migration_example/versions/*.py

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## UNRELEASED
8+
### Added
9+
- Added base implementation of CQRS Pattern.
10+
- Added base implementation of Unit of Work Pattern.
11+
- Added base implementation of Repository Pattern.
12+
- Added base implementation of Message Bus with dependency injection.
13+
- Added base implementation of Redis Message Broker.
14+
- Added higher-order functions to database mappers and factories.
15+
- Added abstract DDD Entity model.
16+
- Added generate now time utility.
17+
- Added root configuration handled by environment variables.
18+
- Added casting to bool from string utility.
19+
- Added json serializer utility.
20+
### Changed
21+
- Renamed project's name from `kingdom-core` to `kingdom-sdk`.
22+
- Increased MyPy rules to be more aggresive.
23+
24+
## [0.2.0] - 2021-10-18
25+
### Added
26+
- Generic start mappers functions to load the ORM.
27+
728
## [0.1.0] - 2021-10-14
829
### Added
930
- Find files utility.

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
Library containing the core modules for the kingdom-python-server.
44

5+
## Test
6+
7+
To test the database package, you need do it manually, running a migration. Make sure the database is configured before.
8+
9+
```bash
10+
cd tests/poc/
11+
alembic revision --autogenerate
12+
alembic upgrade head
13+
```
14+
15+
The rest, run `pytest`.
16+
17+
Don't commit the generated revision.
18+
519
## Installation
620

721
Use the package manager [pip](https://pip.pypa.io/en/stable/) to install `kingdom-core`.
@@ -19,7 +33,7 @@ poetry add kingdom-core
1933
## Usage
2034

2135
```python
22-
from kingdom_core.utils import files
36+
from kingdom_sdk.utils import files
2337

2438
orm_files = files.find("orm.py", "/")
2539
```
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
# Define the package's version.
44
# - Is used for indexing and distributing the package
55
# - Follow the conventions defined by PEP440
6-
__version__ = "0.1.0"
6+
__version__ = "0.3.0dev1"
77

88

9-
def get_base_dir() -> str:
10-
"""Return the absolute path for projetct's root directory."""
9+
def _get_base_dir() -> str:
10+
"""Return the absolute path for kingdom_sdk's root directory."""
1111
path, _ = os.path.split(os.path.dirname(__file__))
1212
return path
1313

1414

15-
def get_src_dir() -> str:
16-
"""Return the absolute path for projetct's source directory."""
15+
def _get_src_dir() -> str:
16+
"""Return the absolute path for kingdom_sdk's source directory."""
1717
return os.path.dirname(__file__)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from typing import Dict, Iterator, Optional
2+
3+
from redis import Redis
4+
5+
from kingdom_sdk import config
6+
from kingdom_sdk.domain.message import Message
7+
from kingdom_sdk.ports.message_broker import AbstractMessageBroker
8+
from kingdom_sdk.utils.serializer import json_dumps
9+
10+
11+
class RedisMessageBroker(AbstractMessageBroker):
12+
_redis: Redis
13+
14+
def __init__(self) -> None:
15+
self._redis = Redis(
16+
host=config.get_redis_host(),
17+
port=config.get_redis_port(),
18+
password=config.get_redis_password(),
19+
)
20+
21+
def publish(
22+
self, channel: str, message: Message, schedule: int = 0
23+
) -> None:
24+
msg = message.__dict__
25+
msg["schedule"] = schedule
26+
del msg["raised_at"] # doesn't make sense to be recreated
27+
self._redis.publish(channel, json_dumps(msg))
28+
29+
def subscribe(self, *channels: str) -> Iterator[Optional[Dict]]:
30+
pubsub = self._redis.pubsub(ignore_subscribe_messages=True)
31+
pubsub.subscribe(*channels)
32+
return pubsub.listen() # type: ignore

0 commit comments

Comments
 (0)