Skip to main content

Core module for Spakky framework to support DI/IoC, AOP, Plugin system, and more.

Project description

Spakky

Core module for Spakky Framework - a Spring-inspired dependency injection framework for Python.

Installation

pip install spakky

Or install with plugins:

pip install spakky[fastapi]
pip install spakky[fastapi,kafka,security]
pip install spakky[all]

Features

  • Dependency Injection: Powerful IoC container with constructor injection
  • Aspect-Oriented Programming: Cross-cutting concerns with @Aspect
  • Plugin System: Extensible architecture via entry points
  • Stereotypes: Semantic annotations (@Controller, @UseCase, etc.)
  • Scopes: Singleton, Prototype, and Context-scoped beans
  • Type-Safe: Built with Python type hints
  • Async First: Native async/await support

Quick Start

Define Pods

from spakky.pod.annotations.pod import Pod

@Pod()
class UserRepository:
    def find_by_id(self, user_id: int) -> User | None:
        # Database query logic
        pass

@Pod()
class UserService:
    def __init__(self, repository: UserRepository) -> None:
        self.repository = repository

    def get_user(self, user_id: int) -> User | None:
        return self.repository.find_by_id(user_id)

Bootstrap Application

from spakky.application.application import SpakkyApplication
from spakky.application.application_context import ApplicationContext
import my_app

app = (
    SpakkyApplication(ApplicationContext())
    .load_plugins()
    .scan(my_app)
    .start()
)

# Get a service from the container
user_service = app.container.get(UserService)

Pod Scopes

from spakky.pod.annotations.pod import Pod

# Singleton (default) - one instance per container
@Pod(scope=Pod.Scope.SINGLETON)
class SingletonService:
    pass

# Prototype - new instance on each request
@Pod(scope=Pod.Scope.PROTOTYPE)
class PrototypeService:
    pass

# Context - scoped to request/context lifecycle
@Pod(scope=Pod.Scope.CONTEXT)
class ContextScopedService:
    pass

Qualifiers

from spakky.pod.annotations.pod import Pod
from spakky.pod.annotations.primary import Primary

# Named qualifier
@Pod(name="mysql")
class MySQLRepository(IRepository):
    pass

@Pod(name="postgres")
class PostgresRepository(IRepository):
    pass

# Primary - preferred when multiple implementations exist
@Primary()
@Pod()
class DefaultRepository(IRepository):
    pass

Stereotypes

from spakky.stereotype.controller import Controller
from spakky.stereotype.usecase import UseCase

@Controller()
class UserController:
    """Groups related handlers together."""
    pass

@UseCase()
class CreateUserUseCase:
    """Encapsulates business logic."""
    pass

Aspect-Oriented Programming

from spakky.aop.aspect import Aspect, AsyncAspect
from spakky.aop.interfaces.aspect import IAspect, IAsyncAspect
from spakky.aop.pointcut import Before, After, Around
from spakky.pod.annotations.order import Order
from spakky.aspects.logging import Logging

# Create custom aspect
@Order(0)
@Aspect()
class LoggingAspect(IAspect):
    @Before(lambda m: Logging.exists(m))
    def before_log(self, *args, **kwargs) -> None:
        print("Before method execution")

    @After(lambda m: Logging.exists(m))
    def after_log(self, *args, **kwargs) -> None:
        print("After method execution")

# Apply to methods
@Pod()
class MyService:
    @Logging()
    def my_method(self) -> str:
        return "Hello"

Async Aspects

from spakky.aop.aspect import AsyncAspect
from spakky.aop.interfaces.aspect import IAsyncAspect
from spakky.aop.pointcut import Around

@Order(0)
@AsyncAspect()
class TimingAspect(IAsyncAspect):
    @Around(lambda m: hasattr(m, "__timed__"))
    async def time_execution(self, joinpoint, *args, **kwargs):
        start = time.time()
        result = await joinpoint(*args, **kwargs)
        elapsed = time.time() - start
        print(f"Execution time: {elapsed:.2f}s")
        return result

Built-in Aspects

from spakky.aspects.logging import Logging
from spakky.aspects.transactional import Transactional

@Pod()
class OrderService:
    @Logging()  # Automatic logging
    @Transactional()  # Transaction management
    async def create_order(self, order: Order) -> Order:
        return await self.repository.save(order)

Plugin System

Plugins extend framework functionality:

# In pyproject.toml
[project.entry-points."spakky.plugins"]
my-plugin = "my_plugin.main:initialize"

# In my_plugin/main.py
from spakky.application.application import SpakkyApplication

def initialize(app: SpakkyApplication) -> None:
    # Register plugin components
    pass

Available Plugins

Plugin Description
spakky-fastapi FastAPI integration
spakky-kafka Apache Kafka event system
spakky-rabbitmq RabbitMQ event system
spakky-security Security utilities
spakky-typer Typer CLI integration

Core Modules

Module Description
spakky.pod Dependency injection container and annotations
spakky.aop Aspect-oriented programming framework
spakky.application Application context and lifecycle
spakky.stereotype Semantic stereotype annotations
spakky.aspects Built-in aspects (Logging, Transactional)
spakky.domain Domain interfaces and abstractions
spakky.service Service layer components
spakky.core Core utilities (proxy, annotation, types)

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

spakky-3.4.0.tar.gz (37.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

spakky-3.4.0-py3-none-any.whl (67.1 kB view details)

Uploaded Python 3

File details

Details for the file spakky-3.4.0.tar.gz.

File metadata

  • Download URL: spakky-3.4.0.tar.gz
  • Upload date:
  • Size: 37.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for spakky-3.4.0.tar.gz
Algorithm Hash digest
SHA256 f17704dffe00e1938b200b913d48d4bd39cd9a287891e5979bd2f3f12d22facf
MD5 ee354650b1515872d70334c38ad85cf2
BLAKE2b-256 ce134095d5b17c645cd825805b364d3af0ec34a7203ca561c41b5114ce9ee999

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky-3.4.0.tar.gz:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file spakky-3.4.0-py3-none-any.whl.

File metadata

  • Download URL: spakky-3.4.0-py3-none-any.whl
  • Upload date:
  • Size: 67.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for spakky-3.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 810c540ec9e6855cd6dc266c7e9de23f25780de87a12cc97bde8b4d6fa717ff0
MD5 c12f0dbcb8ad6c442640b94f748f335a
BLAKE2b-256 7f1a193cfab5e8ce243be64e4346c1e3cb1e9620c8a7195bb1e1260dd4bf1808

See more details on using hashes here.

Provenance

The following attestation bundles were made for spakky-3.4.0-py3-none-any.whl:

Publisher: release.yml on E5presso/spakky-framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page