A powerful Django toolkit for rapid development — auth, caching, logging, serializers, and more.
Project description
Django Swifty
A powerful, lightweight Django toolkit that enhances your development experience with authentication, caching, structured logging, dynamic serializers, and expression evaluation — all with zero platform-specific dependencies.
Installation
pip install django-swifty
With Redis caching support:
pip install django-swifty[redis]
With all optional features:
pip install django-swifty[all]
Quick Start
Add swifty to your INSTALLED_APPS:
INSTALLED_APPS = [
...
"swifty",
]
Features
🔐 Authentication & Authorization
JWT-based authentication with layered permissions via Django REST Framework.
from swifty.auth.permissions import SwiftyPermission
from swifty.viewsets.viewsets import SwiftyViewSet
class AdminPermission(SwiftyPermission):
"""Only allow users with admin or superuser role."""
permission_layers = [
{"path": "role", "allowed": ["admin", "superuser"]},
]
class MyViewSet(SwiftyViewSet):
permission_classes = (AdminPermission,)
def list(self, request):
return Response({"items": []})
Features:
- JWT token rotation and validation via
AccessTokenManager - Layer-based permission checks with dynamic callables
- Per-action permission and authentication class overrides
⚡ Caching
Method-level caching with pluggable backends (Redis by default).
from swifty.cache.manager import cache, cache_property
class ProductService:
redis_cache_pattern = {"prefix": "PRODUCTS", "ttl": 3600, "vary_by": ["user_id"]}
@cache(ttl=1800, static_key="featured")
def get_featured(self):
return Product.objects.filter(featured=True)
@cache_property
def categories(self):
return Category.objects.all()
Features:
@cachedecorator for methods with TTL, static keys, and vary-by@cache_propertyfor cached properties- Configurable cache backend via
settings.CACHE_BACKEND - Auto-reconnection on Redis failures
- Pipeline-based batch cache deletion
Configuration:
# settings.py
import redis
REDIS_CONNECTION_POOL = {
"pool_1": redis.ConnectionPool(host="localhost", port=6379, db=1),
}
# Optional: custom cache backend
# CACHE_BACKEND = "myapp.cache.MyCustomCache"
📝 Structured Logging
Structured logging via structlog with automatic request context binding.
from swifty.logging.logger import SwiftyLoggerMixin
class OrderService(SwiftyLoggerMixin):
def create_order(self, data):
self.logger.info("Creating order", item_count=len(data["items"]))
# ... business logic ...
self.logger.info("Order created", order_id=order.id)
Features:
SwiftyLoggerMixinprovides a cachedself.loggerproperty- Automatic
module.ClassNamelogger naming - Request context binding (user, path, method) via
RequestContext - JSON, console, and key-value formatters
Configuration:
# settings.py
# Swifty auto-configures logging if LOGGING is not set.
# Customize via:
SWIFTY_LOGGING_CONFIG = {
"log_level": logging.DEBUG,
}
# Custom context fields:
CONTEXT_FIELDS_MAPPING = (
("user.username", "username"),
("user.id", "user_id"),
("method", "method"),
("path", "path"),
)
🔄 Dynamic Serializers
Build serializers dynamically from configuration with expression-based calculators and validators.
from swifty.serializers.manager import create_dynamic_serializer
fields_config = [
{"field_name": "name", "type": "CharField", "required": True, "max_length": 100},
{"field_name": "price", "type": "FloatField", "min_value": 0},
{"field_name": "quantity", "type": "IntegerField", "default": 1},
{
"field_name": "total",
"type": "FloatField",
"calculator": {"expression": "price * quantity"},
},
]
MySerializer = create_dynamic_serializer(fields_config)
Available field types:
CharField, EmailField, URLField, UUIDField, IntegerField, FloatField, DecimalField, BooleanField, DateField, DateTimeField, DateRangeField, TimeField, DurationField, ListField, DictField, ChoiceField, MultipleChoiceField, SlugField, FileField, ImageField, JSONField, ReadOnlyField, HiddenField, SectionField, SectionManyField
🧮 Expression Evaluator
Safe mathematical and logical expression evaluation with AST-based security.
from swifty.expressionator.manager import ExpressionatorManager
em = ExpressionatorManager(data={"price": 100, "tax_rate": 0.1, "quantity": 3})
total = em.evaluate("price * quantity * (1 + tax_rate)") # 330.0
is_bulk = em.evaluate("quantity > 5") # False
discount = em.evaluate("max(price * 0.1, 10)") # 10.0
Features:
- AST node whitelisting for security (no arbitrary code execution)
- Math functions (
sin,cos,sqrt,pi, etc.) - Safe builtins (
max,min,abs,len,sum,round, etc.) - Expression compilation caching for performance
- Extensible via custom namespaces
from swifty.expressionator.namespace import ExpressionatorNamespace
class MyNamespace(ExpressionatorNamespace):
def _expr_clamp(self, value, low, high):
return max(low, min(high, value))
em = ExpressionatorManager(data={"x": 150}, namespace=MyNamespace)
em.evaluate("clamp(x, 0, 100)") # 100
🛠 Utilities
Path-based data access:
from swifty.utils.mapper import getpath
data = {"user": {"profile": {"name": "Alice"}}}
getpath(data, "user.profile.name") # "Alice"
getpath(data, "user.missing", "default") # "default"
Dict-to-object conversion:
from swifty.utils.objects import DictObject
obj = DictObject({"user": {"name": "Alice", "tags": ["admin", "staff"]}})
obj.user.name # "Alice"
obj.user.tags # DotList(["admin", "staff"])
Once-trigger decorator:
from swifty.utils.decorators import once_trigger
class ExpensiveService:
@property
@once_trigger
def connection(self):
return create_expensive_connection() # Called only once per instance
Dynamic module importing:
from swifty.utils.importer import import_module_attribute
MyClass = import_module_attribute("myapp.module.MyClass")
🌐 ViewSets
Enhanced DRF ViewSets with JWT auth, structured logging, and request context.
from swifty.viewsets.viewsets import SwiftyViewSet
from swifty.viewsets.exceptions import JsonException
from rest_framework.response import Response
class ProductViewSet(SwiftyViewSet):
def list(self, request):
self.logger.info("Listing products")
return Response({"products": []})
def create(self, request):
if not request.data.get("name"):
raise JsonException({"name": "This field is required."}, status_code=400)
return Response({"created": True}, status=201)
Features:
- Auto request context binding to logger
- Per-action authentication and permission overrides
JsonExceptionfor structured JSON error responses- Double-initialization guard for request objects
Requirements
- Python ≥ 3.10
- Django ≥ 3.2
- Django REST Framework ≥ 3.12
Configuration Reference
| Setting | Description | Default |
|---|---|---|
REDIS_CONNECTION_POOL |
Dict of Redis connection pools | Required for Redis cache |
CACHE_BACKEND |
Custom cache backend class path | swifty.redis.cache.RedisCache |
SWIFTY_LOGGING_CONFIG |
Kwargs for get_logging_config() |
{} |
CONTEXT_FIELDS_MAPPING |
Request context field mappings | See logging section |
Contributing
We welcome contributions! Here's how you can help:
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Authors
- Phuc Le - Initial work - Github
Made with ❤️ by the Django Swifty Team
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 django_swifty-2.0.0.tar.gz.
File metadata
- Download URL: django_swifty-2.0.0.tar.gz
- Upload date:
- Size: 29.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f295b1802b65462dbe7de5f97988bbfdb76699cfc7fedeb0d7c2475f0d2ff386
|
|
| MD5 |
b94c3761db4eca4d1718bd347552bbbb
|
|
| BLAKE2b-256 |
650017e8f3012153c971a160e375b42c18d4c8e46cdf14d3a30b7a932da8e0c4
|
File details
Details for the file django_swifty-2.0.0-py3-none-any.whl.
File metadata
- Download URL: django_swifty-2.0.0-py3-none-any.whl
- Upload date:
- Size: 38.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6a2be9b492b734271f07fc468913378ad0baf93e5682233a4d1dda18168d54a
|
|
| MD5 |
68fad3a534a7795bc5cd63e32f2b1d50
|
|
| BLAKE2b-256 |
7896537d3015ce6c7e0209eb2a44a560dff5a9d8c2988c0c62f36947c8dda725
|