Sweet Tea Factory System
A comprehensive, production-ready Python dependency injection framework using factory patterns with configuration-based object management and lifecycle control.
🚀 Features
- Configuration-Based Dependency Injection: Register classes once, create instances with runtime configuration
- Dual Factory Patterns: Class-based factories (new instances) AND instance-based singletons (shared instances)
- Thread-Safe Registry: Concurrent operations with RLock synchronization
- Type-Safe Generics: Full TypeVar support with
__class_getitem__ - Flexible Key Matching: Support for ClassName, class_name, classname variations
- Optional Dependencies: Graceful handling with custom warnings
- Auto-Registration: Classes automatically registered via package imports
- Lazy Singletons: SingletonFactory.create() for on-demand singleton instantiation
- Comprehensive Testing: 58 tests with 97% coverage
- Rich Documentation: MkDocs with Dracula theme and API reference
🏗️ Dependency Injection
Sweet Tea provides a powerful configuration-based dependency injection system that separates object creation from usage:
Service Registration
# Register services once at application startup
Registry.register("database", PostgreSQLConnection)
Registry.register("cache", RedisCache)
Registry.register("email", SMTPEmailService)
Constructor Injection with Configuration Dictionaries
# Inject configuration dictionaries that define dependencies
class UserService:
def __init__(self, db_config, cache_config):
# Store configuration dictionaries
self.db_config = db_config
self.cache_config = cache_config
# Create factory instances immediately or lazily
self.db = Factory.create(
db_config["class_name"],
configuration=db_config["configuration"]
)
self.cache = SingletonFactory.create(
cache_config["class_name"],
configuration=cache_config["configuration"]
)
# Usage with configuration dictionaries
db_config = {
"class_name": "database",
"configuration": {"host": "prod-db", "port": 5432}
}
cache_config = {
"class_name": "cache",
"configuration": {"host": "redis", "ttl": 3600}
}
user_service = UserService(db_config, cache_config)
Constructor Injection with Factories
# Inject factories into constructors for on-demand dependency creation
class UserService:
def __init__(self, db_factory, cache_factory):
self.db_factory = db_factory # Store factory reference
self.cache_factory = cache_factory
def get_user(self, user_id):
# Create database connection when needed
db = self.db_factory.create("database", configuration={
"host": "prod-db",
"port": 5432,
"credentials": {...}
})
# Create cache when needed
cache = self.cache_factory.create("cache", configuration={
"host": "redis-cluster",
"ttl": 3600
})
# Use dependencies...
user_data = db.query(f"SELECT * FROM users WHERE id = {user_id}")
cached_user = cache.get(f"user:{user_id}")
return user_data or cached_user
Direct Dependency Injection
# Traditional approach: inject pre-configured instances
class UserService:
def __init__(self, database, cache):
self.database = database # Pre-configured instance
self.cache = cache # Pre-configured instance
Lifecycle Management
# Singletons for shared resources
auth_service = SingletonFactory.create("auth", configuration={"jwt_secret": "..."})
# Same instance returned on subsequent calls
# New instances for request-scoped objects
request_handler = Factory.create("request_handler", configuration={"user_id": 123})
# Fresh instance for each request
Benefits
- Separation of Concerns: Configuration separate from implementation
- Testability: Easy mocking and dependency substitution
- Flexibility: Runtime configuration changes without code changes
- Maintainability: Centralized dependency management
- Type Safety: Compile-time interface checking with AbstractFactory
📦 Installation
Using uv (Recommended)
uv add sweet-tea
Using pip
pip install sweet-tea
Using Poetry
poetry add sweet-tea
🏁 Quick Start
from sweet_tea import Registry, Factory, AbstractFactory, SingletonFactory
# === CLASS-BASED FACTORY (Creates new instances each time) ===
Registry.register("database", DatabaseConnection)
db1 = Factory.create("database", configuration={"host": "server1"})
db2 = Factory.create("database", configuration={"host": "server2"})
# db1 ≠ db2 (different instances)
# === LAZY SINGLETON FACTORY (Creates and caches instances on-demand) ===
Registry.register("database", DatabaseConnection)
db3 = SingletonFactory.create("database", configuration={"host": "prod-db", "pool_size": 10})
db4 = SingletonFactory.create("database") # Returns cached instance
# db3 === db4 (same cached instance)
# === TYPE-SAFE ABSTRACT FACTORIES ===
class DatabaseInterface:
def connect(self) -> str: ...
db_factory = AbstractFactory[DatabaseInterface]
db = db_factory.create("postgres") # Only classes implementing DatabaseInterface
Four Factory Patterns
- Factory - Class registration → New instances with configuration
- AbstractFactory - Type-constrained → New instances with type safety
- SingletonFactory - Lazy singletons → Cached instances created on-demand
- InverterFactory - Lazy construction → Class definitions for user-controlled instantiation
📖 Documentation
Complete documentation is available at https://snoodleboot-io.github.io/sweet_tea/
User Guides
- Getting Started - Installation and setup
- Basic Usage - Core factory patterns
- Advanced Features - Type constraints and threading
API Reference
- Registry - Global class registry
- Factory - Basic factory implementation
- AbstractFactory - Generic type-constrained factories
Development
- Contributing - Development setup and guidelines
- Testing - Testing strategy and coverage
🔧 Development
Prerequisites
- Python 3.10 or higher
- uv package manager (recommended)
Setup
# Clone the repository
git clone https://github.com/snoodleboot-io/sweet_tea.git
cd sweet_tea
# Install development dependencies
uv sync
# Install pre-commit hooks
uv run pre-commit install
# Run tests
uv run pytest
# Build documentation locally
uv run mkdocs serve
Code Quality
This project uses several tools to maintain code quality:
- Black: Code formatting
- isort: Import sorting (compatible with Black)
- Ruff: Fast linting and additional formatting
- Bandit: Security scanning
- MyPy: Type checking
All tools run automatically via pre-commit hooks on git commit.
🤝 Contributing
We welcome contributions! Please see our contributing guide for details.
Development Workflow
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and ensure they pass
- Update documentation if needed
- Submit a pull request
📄 License
Copyright © 2025 snoodleboot, LLC. Licensed under the Apache License 2.0.
See LICENSE for the full license text.
🙏 Acknowledgments
- Built with Pydantic for data validation
- Documentation powered by MkDocs with Material theme
- Testing framework: pytest with coverage
- Code quality: Black, Ruff, MyPy
Sweet Tea Factory System - Production-ready factory patterns for Python applications.
Metadata
Release files for sweet_tea 0.2.110
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| sweet_tea-0.2.110.tar.gz | 3.7 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sweet_tea-0.2.110-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.8 MB
Release files / sweet_tea-0.2.110.tar.gz
| Download URL | sweet_tea-0.2.110.tar.gz |
|---|---|
| Size | 3.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6087ef313b76bc726ad554e55477bb6e6403ced5618b967e4f4e80dc858b498c
|
|
BLAKE2b-256 checksum How to use checksums |
ce55314fe07acb0aef75d145fcbbfeea79214cfd0426c4557cc2f7a6e6a2ce43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / sweet_tea-0.2.110-py3-none-any.whl
| Download URL | sweet_tea-0.2.110-py3-none-any.whl |
|---|---|
| Size | 73.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
14d7b8917d522fc67e10d01c790f01fb2dc8651cb3abe8f9e58ba6d4e92a9247
|
|
BLAKE2b-256 checksum How to use checksums |
fcf565e15999198f5d2bd1c3422a935f402e75b629d60c87728a5bb2f9ded602
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for sweet_tea 0.2.110
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.