Explicit, lifecycle-scoped control of side effects
Project description
airlock
Express side effects anywhere. Control whether & when they escape.
tl;dr
import airlock
class Order:
def process(self):
self.status = "processed"
airlock.enqueue(notify_warehouse, self.id)
airlock.enqueue(send_confirmation_email)
The execution context decides when (and whether) your side effects actually get dispatched:
# Production API endpoint: flush at end of request
with airlock.scope():
order.process()
# side effects dispatch here
# Migration: suppress everything
with airlock.scope(policy=airlock.DropAll()):
order.process()
# nothing dispatched
# Test: fail if anything tries to escape
with airlock.scope(policy=airlock.AssertNoEffects()):
order.hopefully_pure_function() # raises if any enqueue() called
# Test: surface the side effects
with airlock.scope(policy=airlock.DropAll()) as scope:
order.process()
assert len(scope.intents) == 2
print((intent.name, intent.args, intent.kwargs) for intent in scope.intents)
# Admin API endpoint: selective control
with airlock.scope(policy=airlock.BlockTasks({"send_confirmation_email"})) as scope:
order.process()
assert len(scope.intents) == 2 # the blocked task remains enqueued while we're in the scope
# side effects dispatch or discard here -- warehouse notified, but no confirmation email sent
Using Django? Maybe with Celery?
# settings.py
MIDDLEWARE = [
# ... other middleware ...
"airlock.integrations.django.AirlockMiddleware",
]
# models.py
import airlock
from . import tasks
class Order(models.Model):
def process(self):
self.status = "processed"
self.save()
airlock.enqueue(tasks.send_confirmation_email, order_id=self.id)
airlock.enqueue(tasks.notify_warehouse, order_id=self.id)
# views.py
def checkout(request):
order = Order.objects.get(id=request.POST['order_id'])
order.process()
return HttpResponse("OK")
# Celery tasks dispatch in middleware, after transaction has committed
Read more: Django integration
Installation
pip install airlock-py
Documentation
Key pages:
- The Problem - Why airlock exists
- Core Model - The 3 concerns (Policy/Executor/Scope)
- Nesting - Nested scopes and safety
- Alternatives - Do I really need this...?
Contributing
See CONTRIBUTING.md for development setup.
License
MIT
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
airlock_py-0.1.0a3.tar.gz
(46.4 kB
view details)
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 airlock_py-0.1.0a3.tar.gz.
File metadata
- Download URL: airlock_py-0.1.0a3.tar.gz
- Upload date:
- Size: 46.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f929cb84a14f4988627ddabb6881ffc59055e17587805eae5305a48c3cf96ca2
|
|
| MD5 |
9452f6684344ff0e411277f983ef799e
|
|
| BLAKE2b-256 |
df96eb00277b14336f815faff788a0347a641672803e840f2270b38c528e84fd
|
File details
Details for the file airlock_py-0.1.0a3-py3-none-any.whl.
File metadata
- Download URL: airlock_py-0.1.0a3-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a13793e4d7dca8e47d5b6655c6ebb5c5591f2b7d71ac78e43d0f05cbb56770b
|
|
| MD5 |
308c956e4ef6af8457e0f69003685033
|
|
| BLAKE2b-256 |
4c38c2734078f2cb3a47cc2c40e94a02bd9002ca5eaf7a7d4a28665a5e040d6e
|