Data access layer for Spakky Framework (Repository implementations, ORM integration)
Project description
Spakky Data
Data access layer abstractions for Spakky Framework.
Installation
pip install spakky-data
Features
- Repository Pattern: Generic repository interfaces for aggregate persistence
- Transaction Management: Abstract transaction classes with autocommit support
- External Proxy: Proxy pattern for external service/storage data access (NOT for database)
Design Principles
Repository is for Persistence Only
Repositories handle CRUD operations for domain aggregates only.
Do NOT add query methods like find_by_xxx, search_xxx to repositories.
Complex queries should be implemented directly in QueryUseCase using ORM/SQL. This prevents domain pollution by keeping query concerns out of the domain layer.
# ❌ Wrong: Query concerns in repository
class IUserRepository:
def find_by_email(self, email: str) -> User | None: ...
# ✅ Correct: Direct implementation in QueryUseCase
@QueryUseCase()
class FindUserByEmailUseCase(IAsyncQueryUseCase[FindUserByEmailQuery, UserDTO]):
async def run(self, query: FindUserByEmailQuery) -> UserDTO:
# Use ORM/SQL directly
...
External Proxy vs Repository
| Aspect | Repository | External Proxy |
|---|---|---|
| Purpose | Domain aggregate persistence | External service data access |
| Target | Database (via ORM) | REST API, gRPC, legacy systems |
| Operations | CRUD (save, delete, get) | Read-only (get, range) |
| Domain | Internal bounded context | External services |
Quick Start
Repository Pattern
Define repository interfaces for your domain aggregates:
from abc import abstractmethod
from uuid import UUID
from spakky.data.persistency.repository import IAsyncGenericRepository
from spakky.domain.models.aggregate_root import AbstractAggregateRoot
class User(AbstractAggregateRoot[UUID]):
name: str
email: str
# Repository interface - CRUD only, no query methods
class IUserRepository(IAsyncGenericRepository[User, UUID]):
pass # get, get_or_none, contains, range, save, save_all, delete, delete_all
Transaction Management
Use abstract transactions for database operations:
from spakky.data.persistency.transaction import AbstractAsyncTransaction
class SQLAlchemyTransaction(AbstractAsyncTransaction):
def __init__(self, session_factory, autocommit: bool = True) -> None:
super().__init__(autocommit)
self.session_factory = session_factory
self.session = None
async def initialize(self) -> None:
self.session = self.session_factory()
async def dispose(self) -> None:
await self.session.close()
async def commit(self) -> None:
await self.session.commit()
async def rollback(self) -> None:
await self.session.rollback()
Usage with context manager:
async with transaction:
user = await repository.get(user_id)
user.name = "New Name"
await repository.save(user)
# Automatically commits on success, rollbacks on exception
External Proxy Pattern
Access external services (NOT databases) with proxy interfaces. Use this for REST APIs, gRPC services, legacy systems, etc.
from spakky.data.external.proxy import ProxyModel, IAsyncGenericProxy
# Data model from external payment service
class PaymentInfo(ProxyModel[str]):
transaction_id: str
amount: int
status: str
# Proxy interface for external payment service
class IPaymentProxy(IAsyncGenericProxy[PaymentInfo, str]):
pass
# Implementation calls external API
class PaymentServiceProxy(IPaymentProxy):
async def get(self, proxy_id: str) -> PaymentInfo:
response = await self._http_client.get(f"/payments/{proxy_id}")
return PaymentInfo(...)
API Reference
Persistency
| Class | Description |
|---|---|
IGenericRepository |
Sync generic repository interface |
IAsyncGenericRepository |
Async generic repository interface |
AbstractTransaction |
Sync transaction with context manager |
AbstractAsyncTransaction |
Async transaction with context manager |
EntityNotFoundError |
Raised when entity not found |
External
| Class | Description |
|---|---|
ProxyModel |
Base class for external service data models |
IGenericProxy |
Sync proxy interface |
IAsyncGenericProxy |
Async proxy interface |
Errors
| Class | Description |
|---|---|
AbstractSpakkyPersistencyError |
Base error for persistency operations |
AbstractSpakkyExternalError |
Base error for external service operations |
Related Packages
| Package | Description |
|---|---|
spakky-domain |
DDD building blocks (Entity, AggregateRoot, ValueObject) |
spakky-event |
Event publisher/consumer interfaces |
License
MIT License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file spakky_data-6.1.0.tar.gz.
File metadata
- Download URL: spakky_data-6.1.0.tar.gz
- Upload date:
- Size: 6.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d7d4efd0438468d80f2fba2a5dcaa5a9fef18c8e9b026163250d7fcedc28b9c3
|
|
| MD5 |
e1a8275bccf54b7cb4dc404d053d2ae6
|
|
| BLAKE2b-256 |
3e31c5552dd6822c04ec970330b95f37dc03dcbbad2afc67925036ce0ffa30ea
|
Provenance
The following attestation bundles were made for spakky_data-6.1.0.tar.gz:
Publisher:
release.yml on E5presso/spakky-framework
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spakky_data-6.1.0.tar.gz -
Subject digest:
d7d4efd0438468d80f2fba2a5dcaa5a9fef18c8e9b026163250d7fcedc28b9c3 - Sigstore transparency entry: 1110085044
- Sigstore integration time:
-
Permalink:
E5presso/spakky-framework@c72d9ed481523a919c2a298454730dd87352010a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/E5presso
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c72d9ed481523a919c2a298454730dd87352010a -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file spakky_data-6.1.0-py3-none-any.whl.
File metadata
- Download URL: spakky_data-6.1.0-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fa6cc6e8007e0d9cf09b231339a47ed6cb9b055001e6061e1805f4aa86f18de
|
|
| MD5 |
44903d527d200251f1d0f330e4576027
|
|
| BLAKE2b-256 |
7c17916e73363194e3d926bfb6c54a598a35929cb427a809086116e95a35a422
|
Provenance
The following attestation bundles were made for spakky_data-6.1.0-py3-none-any.whl:
Publisher:
release.yml on E5presso/spakky-framework
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
spakky_data-6.1.0-py3-none-any.whl -
Subject digest:
9fa6cc6e8007e0d9cf09b231339a47ed6cb9b055001e6061e1805f4aa86f18de - Sigstore transparency entry: 1110085055
- Sigstore integration time:
-
Permalink:
E5presso/spakky-framework@c72d9ed481523a919c2a298454730dd87352010a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/E5presso
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c72d9ed481523a919c2a298454730dd87352010a -
Trigger Event:
workflow_dispatch
-
Statement type: