django-webhook-subscriber 2.0.0__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/PKG-INFO +49 -1
  2. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/README.md +48 -0
  3. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/delivery.py +15 -9
  4. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/serializers.py +13 -0
  5. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_delivery.py +72 -0
  6. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber.egg-info/PKG-INFO +49 -1
  7. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/pyproject.toml +1 -1
  8. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/LICENSE +0 -0
  9. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/__init__.py +0 -0
  10. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/admin.py +0 -0
  11. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/apps.py +0 -0
  12. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/conf.py +0 -0
  13. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/http.py +0 -0
  14. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/__init__.py +0 -0
  15. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/__init__.py +0 -0
  16. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/webhook.py +0 -0
  17. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/webhook_cache.py +0 -0
  18. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/webhook_logs.py +0 -0
  19. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/webhook_performance_test.py +0 -0
  20. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/webhook_send.py +0 -0
  21. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/management/commands/webhook_status.py +0 -0
  22. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/managers.py +0 -0
  23. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/migrations/0001_initial.py +0 -0
  24. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/migrations/0002_remove_webhookregistry_content_type_and_more.py +0 -0
  25. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/migrations/__init__.py +0 -0
  26. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/models.py +0 -0
  27. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tasks.py +0 -0
  28. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/__init__.py +0 -0
  29. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/factories.py +0 -0
  30. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/settings.py +0 -0
  31. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_http.py +0 -0
  32. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_managers.py +0 -0
  33. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_models.py +0 -0
  34. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_serializers.py +0 -0
  35. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_tasks.py +0 -0
  36. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/tests/test_utils.py +0 -0
  37. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/utils.py +0 -0
  38. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber/validators.py +0 -0
  39. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber.egg-info/SOURCES.txt +0 -0
  40. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber.egg-info/dependency_links.txt +0 -0
  41. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber.egg-info/requires.txt +0 -0
  42. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/django_webhook_subscriber.egg-info/top_level.txt +0 -0
  43. {django_webhook_subscriber-2.0.0 → django_webhook_subscriber-2.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-webhook-subscriber
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: A Django package designed to handle webhook creation, management, and delivery.
5
5
  Author-email: 42 Portugal <root@42porto.com>
6
6
  Classifier: Environment :: Web Environment
@@ -172,6 +172,53 @@ subscriber.serializer_class = "myapp.serializers.UserWebhookSerializer"
172
172
  subscriber.save()
173
173
  ```
174
174
 
175
+ ### 4. Raw Payload (No Metadata Wrapper)
176
+
177
+ By default, webhook payloads include metadata and the serialized data is nested inside a `fields` key:
178
+
179
+ ```json
180
+ {
181
+ "pk": 1,
182
+ "event_signal": "created",
183
+ "source": "auth.user",
184
+ "timestamp": "2026-02-05T10:30:00Z",
185
+ "fields": {
186
+ "id": 1,
187
+ "name": "John Doe",
188
+ "email": "john@example.com"
189
+ }
190
+ }
191
+ ```
192
+
193
+ If you prefer a raw payload containing only the serialized data (without the metadata wrapper), use the `WebhookRawPayloadMixin`:
194
+
195
+ ```python
196
+ from rest_framework import serializers
197
+ from django.contrib.auth import get_user_model
198
+ from django_webhook_subscriber.serializers import WebhookRawPayloadMixin
199
+
200
+ User = get_user_model()
201
+
202
+ class UserRawWebhookSerializer(WebhookRawPayloadMixin, serializers.ModelSerializer):
203
+ class Meta:
204
+ model = User
205
+ fields = ["id", "name", "email"]
206
+
207
+ # Update subscriber to use the raw payload serializer
208
+ subscriber.serializer_class = "myapp.serializers.UserRawWebhookSerializer"
209
+ subscriber.save()
210
+ ```
211
+
212
+ With `WebhookRawPayloadMixin`, the webhook payload will be just the serialized data:
213
+
214
+ ```json
215
+ {
216
+ "id": 1,
217
+ "name": "John Doe",
218
+ "email": "john@example.com"
219
+ }
220
+ ```
221
+
175
222
  ## Configuration
176
223
 
177
224
  Configure the package in your Django settings:
@@ -632,6 +679,7 @@ Set up cron jobs for maintenance:
632
679
  ```
633
680
 
634
681
  3. **Monitor delivery performance:**
682
+
635
683
  ```bash
636
684
  # Regular performance testing
637
685
  python manage.py webhook_performance_test --model=myapp.User --event=test --object-count=10
@@ -137,6 +137,53 @@ subscriber.serializer_class = "myapp.serializers.UserWebhookSerializer"
137
137
  subscriber.save()
138
138
  ```
139
139
 
140
+ ### 4. Raw Payload (No Metadata Wrapper)
141
+
142
+ By default, webhook payloads include metadata and the serialized data is nested inside a `fields` key:
143
+
144
+ ```json
145
+ {
146
+ "pk": 1,
147
+ "event_signal": "created",
148
+ "source": "auth.user",
149
+ "timestamp": "2026-02-05T10:30:00Z",
150
+ "fields": {
151
+ "id": 1,
152
+ "name": "John Doe",
153
+ "email": "john@example.com"
154
+ }
155
+ }
156
+ ```
157
+
158
+ If you prefer a raw payload containing only the serialized data (without the metadata wrapper), use the `WebhookRawPayloadMixin`:
159
+
160
+ ```python
161
+ from rest_framework import serializers
162
+ from django.contrib.auth import get_user_model
163
+ from django_webhook_subscriber.serializers import WebhookRawPayloadMixin
164
+
165
+ User = get_user_model()
166
+
167
+ class UserRawWebhookSerializer(WebhookRawPayloadMixin, serializers.ModelSerializer):
168
+ class Meta:
169
+ model = User
170
+ fields = ["id", "name", "email"]
171
+
172
+ # Update subscriber to use the raw payload serializer
173
+ subscriber.serializer_class = "myapp.serializers.UserRawWebhookSerializer"
174
+ subscriber.save()
175
+ ```
176
+
177
+ With `WebhookRawPayloadMixin`, the webhook payload will be just the serialized data:
178
+
179
+ ```json
180
+ {
181
+ "id": 1,
182
+ "name": "John Doe",
183
+ "email": "john@example.com"
184
+ }
185
+ ```
186
+
140
187
  ## Configuration
141
188
 
142
189
  Configure the package in your Django settings:
@@ -597,6 +644,7 @@ Set up cron jobs for maintenance:
597
644
  ```
598
645
 
599
646
  3. **Monitor delivery performance:**
647
+
600
648
  ```bash
601
649
  # Regular performance testing
602
650
  python manage.py webhook_performance_test --model=myapp.User --event=test --object-count=10
@@ -8,7 +8,7 @@ from django.utils import timezone
8
8
  from django.utils.module_loading import import_string
9
9
 
10
10
  from .conf import rest_webhook_settings as settings
11
- from .serializers import serialize_webhook_instance
11
+ from .serializers import WebhookRawPayloadMixin, serialize_webhook_instance
12
12
  from .tasks import process_webhook_delivery_batch
13
13
  from .utils import (
14
14
  clear_content_type_cache,
@@ -184,14 +184,20 @@ class WebhookDeliveryProcessor:
184
184
  )
185
185
 
186
186
  # Build standard payload structure
187
- payload = {
188
- "pk": instance.pk,
189
- "event_signal": event_name,
190
- "source": f"{instance._meta.app_label}."
191
- f"{instance._meta.model_name}",
192
- "timestamp": timezone.now().isoformat(),
193
- "fields": fields_data,
194
- }
187
+ if serializer_class and issubclass(
188
+ serializer_class, WebhookRawPayloadMixin
189
+ ):
190
+ # Raw payload mixin - use fields data directly
191
+ payload = fields_data
192
+ else:
193
+ payload = {
194
+ "pk": instance.pk,
195
+ "event_signal": event_name,
196
+ "source": f"{instance._meta.app_label}."
197
+ f"{instance._meta.model_name}",
198
+ "timestamp": timezone.now().isoformat(),
199
+ "fields": fields_data,
200
+ }
195
201
 
196
202
  return payload
197
203
 
@@ -39,3 +39,16 @@ def serialize_webhook_instance(instance, field_serializer=None):
39
39
  serialized_data = serializer.data
40
40
  # Return the serialized data
41
41
  return serialized_data
42
+
43
+
44
+ class WebhookRawPayloadMixin:
45
+ """
46
+ Mixin to indicate that the webhook payload should be sent as raw data.
47
+
48
+ By default, the payload includes extra fields and the serialized
49
+ instance data goes inside a 'fields' key.
50
+ By having this mixin, the webhook payload will be just the
51
+ serialized instance data.
52
+ """
53
+
54
+ pass
@@ -220,6 +220,78 @@ class WebhookDeliveryProcessorTests(TestCase):
220
220
  self.assertIn("error", result)
221
221
  self.assertEqual(result["fields"], {})
222
222
 
223
+ @patch("django_webhook_subscriber.delivery.serialize_webhook_instance")
224
+ @patch("django_webhook_subscriber.delivery.import_string")
225
+ def test_generate_payload_with_raw_payload_mixin(
226
+ self, mock_import_string, mock_serialize
227
+ ):
228
+ """Test that WebhookRawPayloadMixin returns only serialized data."""
229
+ from rest_framework import serializers
230
+
231
+ from django_webhook_subscriber.serializers import (
232
+ WebhookRawPayloadMixin,
233
+ )
234
+
235
+ # Create a serializer class with WebhookRawPayloadMixin
236
+ class RawPayloadSerializer(
237
+ WebhookRawPayloadMixin, serializers.ModelSerializer
238
+ ):
239
+ class Meta:
240
+ model = models.WebhookDeliveryLog
241
+ fields = ["id", "payload"]
242
+
243
+ mock_import_string.return_value = RawPayloadSerializer
244
+ mock_serialize.return_value = {"id": 1, "payload": {"key": "value"}}
245
+
246
+ result = self.processor._generate_payload(
247
+ self.instance,
248
+ "created",
249
+ "some.path.RawPayloadSerializer",
250
+ )
251
+
252
+ # With WebhookRawPayloadMixin, the payload should be the serialized
253
+ # data directly, without metadata wrapper
254
+ self.assertEqual(result, {"id": 1, "payload": {"key": "value"}})
255
+ self.assertNotIn("pk", result)
256
+ self.assertNotIn("event_signal", result)
257
+ self.assertNotIn("source", result)
258
+ self.assertNotIn("timestamp", result)
259
+ self.assertNotIn("fields", result)
260
+
261
+ @patch("django_webhook_subscriber.delivery.serialize_webhook_instance")
262
+ @patch("django_webhook_subscriber.delivery.import_string")
263
+ def test_generate_payload_without_raw_payload_mixin(
264
+ self, mock_import_string, mock_serialize
265
+ ):
266
+ """Test that regular serializers return payload with metadata."""
267
+ from rest_framework import serializers
268
+
269
+ # Create a regular serializer without WebhookRawPayloadMixin
270
+ class RegularSerializer(serializers.ModelSerializer):
271
+ class Meta:
272
+ model = models.WebhookDeliveryLog
273
+ fields = ["id", "payload"]
274
+
275
+ mock_import_string.return_value = RegularSerializer
276
+ mock_serialize.return_value = {"id": 1, "payload": {"key": "value"}}
277
+
278
+ result = self.processor._generate_payload(
279
+ self.instance,
280
+ "created",
281
+ "some.path.RegularSerializer",
282
+ )
283
+
284
+ # Without WebhookRawPayloadMixin, the payload should include metadata
285
+ self.assertEqual(result["pk"], 1)
286
+ self.assertEqual(result["event_signal"], "created")
287
+ self.assertEqual(
288
+ result["source"], "django_webhook_subscriber.webhookdeliverylog"
289
+ )
290
+ self.assertIn("timestamp", result)
291
+ self.assertEqual(
292
+ result["fields"], {"id": 1, "payload": {"key": "value"}}
293
+ )
294
+
223
295
  def test_deliver_webhooks_on_no_subscriptions(self):
224
296
  result = self.processor._deliver_webhooks([])
225
297
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-webhook-subscriber
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: A Django package designed to handle webhook creation, management, and delivery.
5
5
  Author-email: 42 Portugal <root@42porto.com>
6
6
  Classifier: Environment :: Web Environment
@@ -172,6 +172,53 @@ subscriber.serializer_class = "myapp.serializers.UserWebhookSerializer"
172
172
  subscriber.save()
173
173
  ```
174
174
 
175
+ ### 4. Raw Payload (No Metadata Wrapper)
176
+
177
+ By default, webhook payloads include metadata and the serialized data is nested inside a `fields` key:
178
+
179
+ ```json
180
+ {
181
+ "pk": 1,
182
+ "event_signal": "created",
183
+ "source": "auth.user",
184
+ "timestamp": "2026-02-05T10:30:00Z",
185
+ "fields": {
186
+ "id": 1,
187
+ "name": "John Doe",
188
+ "email": "john@example.com"
189
+ }
190
+ }
191
+ ```
192
+
193
+ If you prefer a raw payload containing only the serialized data (without the metadata wrapper), use the `WebhookRawPayloadMixin`:
194
+
195
+ ```python
196
+ from rest_framework import serializers
197
+ from django.contrib.auth import get_user_model
198
+ from django_webhook_subscriber.serializers import WebhookRawPayloadMixin
199
+
200
+ User = get_user_model()
201
+
202
+ class UserRawWebhookSerializer(WebhookRawPayloadMixin, serializers.ModelSerializer):
203
+ class Meta:
204
+ model = User
205
+ fields = ["id", "name", "email"]
206
+
207
+ # Update subscriber to use the raw payload serializer
208
+ subscriber.serializer_class = "myapp.serializers.UserRawWebhookSerializer"
209
+ subscriber.save()
210
+ ```
211
+
212
+ With `WebhookRawPayloadMixin`, the webhook payload will be just the serialized data:
213
+
214
+ ```json
215
+ {
216
+ "id": 1,
217
+ "name": "John Doe",
218
+ "email": "john@example.com"
219
+ }
220
+ ```
221
+
175
222
  ## Configuration
176
223
 
177
224
  Configure the package in your Django settings:
@@ -632,6 +679,7 @@ Set up cron jobs for maintenance:
632
679
  ```
633
680
 
634
681
  3. **Monitor delivery performance:**
682
+
635
683
  ```bash
636
684
  # Regular performance testing
637
685
  python manage.py webhook_performance_test --model=myapp.User --event=test --object-count=10
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "django-webhook-subscriber"
7
- version = "2.0.0"
7
+ version = "2.1.0"
8
8
  dependencies = [
9
9
  "Django>=5.0,<5.3",
10
10
  "djangorestframework>=3.15.0,<3.17",