Architecture Patterns with Python Example Code

repository·master·Indexed 25 days ago

https://github.com/cosmicpython/code

Example application code for the 'Architecture Patterns with Python' book. The repository demonstrates various architectural patterns through incremental, chapter-based development using Git branches. It includes a Flask API, SQLAlchemy persistence, and a message bus, with support for Docker and Python 3.8 environments.

Tokens
4.1K
Snippets
9
Records
34
Agent score
83%

What's inside cosmicpython-code

  1. Overview of the Cosmic Python Example Code

    master
    This repository contains example application code for the book 'Architecture Patterns with Python'. The code is organized by chapters and exercises using Git branches. Each chapter branch represents the state of the code at the end of that chapter. To code along with a chapter, check out the branch for the previous chapter.
  2. Run tests

    master

    You can run the test suite using the Makefile or directly via pytest if you are using a local virtual environment. The tests are categorized into unit, integration, and end-to-end (e2e) tests.

    # Using Makefile
    make test
    # or individual types:
    make unit-tests
    make integration-tests
    make e2e-tests
    
    # Using local virtualenv
    make up
    pytest tests/unit
    pytest tests/integration
    pytest tests/e2e
  3. Set up the project using Docker

    master

    From chapter 3 onwards, you can use Docker and Docker Compose to run the application. Use the provided Makefile to build and start the containers.

    Requirements:

    • Docker with docker-compose
    make build
    make up
    # or
    make all # builds, brings containers up, runs tests
  4. Run the Redis event consumer entrypoint

    master

    The redis_eventconsumer.py script serves as an entrypoint for an event-driven consumer that listens to Redis Pub/Sub channels. It subscribes to the change_batch_quantity channel and processes incoming messages by converting them into ChangeBatchQuantity commands, which are then dispatched via the application's command bus.

    To use this entrypoint, ensure that:

    1. A Redis instance is running and accessible via the configuration provided by allocation.config.get_redis_host_and_port().
    2. The allocation package is installed and configured.
    3. Messages published to the change_batch_quantity channel follow the expected JSON format: {"batchref": <string>, "qty": <number>}.
  5. Configure Email service connection details

    master

    The get_email_host_and_port() function returns a dictionary containing connection details for the email service. It uses the following environment variable:

    • EMAIL_HOST: The email host (defaults to localhost).

    Note: If EMAIL_HOST is set to localhost, the port defaults to 11025 and the http_port defaults to 18025. For any other host, port defaults to 1025 and http_port defaults to 8025.

  6. Configure Redis connection details

    master

    The get_redis_host_and_port() function returns a dictionary containing the Redis connection parameters. It uses the following environment variable:

    • REDIS_HOST: The Redis host (defaults to localhost).

    Note: If REDIS_HOST is set to localhost, the port defaults to 63791. For any other host, it defaults to 6379.

  7. Configure PostgreSQL connection URI

    master

    The get_postgres_uri() function constructs a PostgreSQL connection string. It uses the following environment variables:

    • DB_HOST: The database host (defaults to localhost).
    • DB_PASSWORD: The database password (defaults to abc123).

    Note: If DB_HOST is set to localhost, the port defaults to 54321. For any other host, it defaults to 5432. The username is fixed as allocation and the database name is fixed as allocation.

  8. Configure the application environment via docker-compose.yml

    master

    The project uses Docker Compose to orchestrate several services: api, redis_pubsub, postgres, redis, and mailhog.

    Service Environment Variables

    When running the services, the following environment variables are used to configure connectivity and behavior:

    For api and redis_pubsub services:

    • DB_HOST: Hostname for the PostgreSQL database (default: postgres).
    • DB_PASSWORD: Password for the database (default: abc123).
    • REDIS_HOST: Hostname for the Redis instance (default: redis).
    • EMAIL_HOST: Hostname for the MailHog instance (default: mailhog).
    • PYTHONDONTWRITEBYTECODE: Set to 1 to prevent Python from writing .pyc files.

    Specific to api service:

    • API_HOST: Hostname for the API (default: api).
    • FLASK_APP: Path to the Flask application entrypoint (default: allocation/entrypoints/flask_app.py).
    • FLASK_DEBUG: Set to 1 to enable Flask debug mode.
    • PYTHONUNBUFFERED: Set to 1 to ensure logs are sent to stdout/stderr immediately.

    Specific to postgres service:

    • POSTGRES_USER: Username for the database (default: allocation).
    • POSTGRES_PASSWORD: Password for the database (default: abc123).
  9. Implement the Unit of Work pattern with AbstractUnitOfWork

    master

    The AbstractUnitOfWork defines the interface for managing transaction boundaries and coordinating multiple repositories. It provides a context manager interface and a method to collect domain events from repositories.

    Key methods:

    • __enter__: Starts the transaction context.
    • __exit__: Automatically calls rollback() if an exception occurs.
    • commit(): Triggers the internal _commit() method to persist changes.
    • collect_new_events(): A generator that yields domain events from all products currently tracked by the products repository.