Skip to content

Commit

Permalink
chore: add missing documentation and readme files
Browse files Browse the repository at this point in the history
  • Loading branch information
raf-nr committed Oct 2, 2024
1 parent 00d24e8 commit ddb8541
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 6 deletions.
22 changes: 22 additions & 0 deletions internal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Internal Module

## Description

This application is built upon the principles of Clean Architecture. Clean Architecture emphasizes separation of concerns, making the codebase easier to maintain, test, and scale. The architecture is structured to allow flexibility and independence from frameworks, which enhances the portability of the code.

For more information about Clean Architecture, you may refer to the following resources:
- [Clean Architecture: A Craftsman's Guide to Software Structure and Design by Robert C. Martin](https://www.oreilly.com/library/view/clean-architecture-a/9780134494272/)
- [Clean Architecture](https://github.com/preslavmihaylov/booknotes/tree/master/architecture/clean-architecture)

## Structure

The internal module is organized into the following components:

- **Domain**: Contains the core business logic and entities. This is where the application's fundamental rules are defined.
- **Use Case**: Represents application-specific business rules and orchestrates the flow of data between the domain and external layers.
- **Unit of Work (UoW)**: Manages transactional boundaries and ensures that a series of operations can be committed or rolled back as a single unit.
- **Repository**: Abstracts the data access layer, providing methods for retrieving and storing entities.
- **Worker**: Provides abstractions for running background tasks and managing asynchronous operations.
- **DTO (Data Transfer Object)**: Handles the data transfer between use cases and the external world, ensuring that only the necessary data is exposed and passed around.

This structure facilitates maintainability and scalability by enforcing clear boundaries and responsibilities within the application.
8 changes: 8 additions & 0 deletions internal/dto/repository/exception.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
class ModelNotFoundException(Exception):
"""
Exception raised when a storage model is not found in some data storage.
This exception may be thrown only by the repository.
"""
def __init__(self, message: str):
"""
Initializes an instance of ModelNotFoundException with a default message.
"""
super().__init__(message)
7 changes: 7 additions & 0 deletions internal/infrastructure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# infrastructure module
This module implements an infrastructure layer from a pure architecture.

## submodules
`background_task` - implementation of tasks execution in the background. Provides functionality for specific worker implementations.

`data_storage` - provides various tools and functions for managing data stores and transactions in them - settings, connections, contexts, migrations, etc.
7 changes: 6 additions & 1 deletion internal/infrastructure/data_storage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ This module is responsible for managing the configuration and settings related t
### settings
`settings.py` contains all the settings for working with the data store. Through them you can get the URL to connect to the database, file paths, and so on.

### context
This module(`data_storage`) and all its submodules that represent some kind of storage must contain an implementation of the context - a “bridge” between the repositories and the data storage system. The context accumulates data within itself and provides transactions

`context.py` contains a unique context that encapsulates the logic of all other contexts.

### relational
The `flat` module contains the logic for interacting with local file storages. [Read more.](flat/README.md)

### relational
The `relational` module contains the logic for interacting with relational databases using SQLAlchemy. [Read more.](relational/README.md)


## Extensibility
If you need to add a new database or other data storage, simply create the appropriate module with the implementation in this module, and also write all the necessary settings in `settings.py`.
You should also implement a context for your repository and extend a unique context for it.
3 changes: 3 additions & 0 deletions internal/repository/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# repository module
This module contains implementations of all repositories.
To implement your repository, create a module here for the repository that the repository works with (or use an existing one), and then implement the repository WITHOUT inheriting from interfaces. It is important that in the repository implementation all operations occur through the universal context from the `internal.infrastructure.data_storage` directory.
9 changes: 5 additions & 4 deletions internal/uow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@ This module implements the Unit of Work (UoW) pattern, which is designed to mana
The Unit of Work pattern manages transactional operations within a business process. It groups multiple changes to a data store into a single logical transaction, ensuring that either all operations succeed or none do. This is particularly useful for preventing partial updates, ensuring data integrity, and managing rollbacks in case of errors.

## Implementation
The Unit Of Work class works with a DataStorageContext interface, which defines essential methods like commit, flush, rollback, and close. This allows different types of data storage (e.g., relational databases, file systems) to be plugged in while adhering to a unified transaction control mechanism.
The Unit Of Work class works with a DataStorageContext interface (it is assumed that the generic context from `internal.infrastructure.data_storage` will be used), which defines essential methods like commit, flush, rollback, and close. This allows different types of data storage (e.g., relational databases, file systems) to be plugged in while adhering to a unified transaction control mechanism.

To use UoW in your use case, you need to implement the DataStorageContext interface for your data store (if not already done), and you also need to have a repository implementation that supports working with your DataStorageContext.
To use UoW in your use case, you need to implement the DataStorageContext interface for your data store (if not already done), and then inject your context into the universal context from the infrastructure module.

### Example
```python

from typing import Protocol, Type
from uuid import UUID, uuid4
from internal.infrastructure.data_storage import get_context_maker
from sqlalchemy.orm import Session
from internal.uow import UnitOfWork, DataStorageContext

class DatasetRepo(Protocol):
def create(self, file_id: UUID, context: DataStorageContext) -> None: ...

def create_uow(context_maker: Type[Session]) -> UnitOfWork:
return UnitOfWork(context_maker=context_maker)
def create_uow() -> UnitOfWork:
return UnitOfWork(context_maker=get_context_maker())

def create_two_datasets(
uow: UnitOfWork,
Expand Down
2 changes: 1 addition & 1 deletion internal/usecase/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ All repository interfaces must be created using Python’s `Protocol` to ensure
Implement the use case. The use case should manage domain entities directly but interact with repositories, services, and external components strictly through interfaces.

### 4. Implement data storage context
Implement interface `DataStorageContext` for your data storage. Place it in the `internal.infrastructure.data_storage` module.
Implement interface `DataStorageContext` for your data storage and then add it into the universal context from `internal.infrastructure.data_storage` module.

### 4. Implement the repository
If the repository isn't implemented, you will need to provide a concrete implementation for the repository interface. Place this in the `internal.repository` module.

0 comments on commit ddb8541

Please sign in to comment.