stapel-cdn 0.4.1__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 (60) hide show
  1. stapel_cdn-0.4.1/LICENSE +21 -0
  2. stapel_cdn-0.4.1/PKG-INFO +58 -0
  3. stapel_cdn-0.4.1/README.md +34 -0
  4. stapel_cdn-0.4.1/__init__.py +47 -0
  5. stapel_cdn-0.4.1/actions.py +23 -0
  6. stapel_cdn-0.4.1/admin.py +525 -0
  7. stapel_cdn-0.4.1/apps.py +30 -0
  8. stapel_cdn-0.4.1/conf.py +105 -0
  9. stapel_cdn-0.4.1/conftest.py +53 -0
  10. stapel_cdn-0.4.1/dto.py +92 -0
  11. stapel_cdn-0.4.1/errors.py +32 -0
  12. stapel_cdn-0.4.1/forms.py +99 -0
  13. stapel_cdn-0.4.1/functions.py +77 -0
  14. stapel_cdn-0.4.1/gdpr.py +94 -0
  15. stapel_cdn-0.4.1/management/__init__.py +0 -0
  16. stapel_cdn-0.4.1/management/commands/__init__.py +0 -0
  17. stapel_cdn-0.4.1/management/commands/benchmark_imgproc.py +107 -0
  18. stapel_cdn-0.4.1/management/commands/consume_cdn_events.py +52 -0
  19. stapel_cdn-0.4.1/migrations/0001_initial.py +107 -0
  20. stapel_cdn-0.4.1/migrations/__init__.py +1 -0
  21. stapel_cdn-0.4.1/models.py +521 -0
  22. stapel_cdn-0.4.1/py.typed +0 -0
  23. stapel_cdn-0.4.1/pyproject.toml +44 -0
  24. stapel_cdn-0.4.1/schemas/consumes/user.deleted.json +13 -0
  25. stapel_cdn-0.4.1/schemas/consumes/user.deletion_initiated.json +13 -0
  26. stapel_cdn-0.4.1/serializers.py +317 -0
  27. stapel_cdn-0.4.1/services.py +440 -0
  28. stapel_cdn-0.4.1/setup.cfg +4 -0
  29. stapel_cdn-0.4.1/stapel_cdn.egg-info/PKG-INFO +58 -0
  30. stapel_cdn-0.4.1/stapel_cdn.egg-info/SOURCES.txt +108 -0
  31. stapel_cdn-0.4.1/stapel_cdn.egg-info/dependency_links.txt +1 -0
  32. stapel_cdn-0.4.1/stapel_cdn.egg-info/requires.txt +12 -0
  33. stapel_cdn-0.4.1/stapel_cdn.egg-info/top_level.txt +1 -0
  34. stapel_cdn-0.4.1/storage.py +34 -0
  35. stapel_cdn-0.4.1/tasks.py +152 -0
  36. stapel_cdn-0.4.1/tests/__init__.py +0 -0
  37. stapel_cdn-0.4.1/tests/test_admin.py +264 -0
  38. stapel_cdn-0.4.1/tests/test_commands.py +145 -0
  39. stapel_cdn-0.4.1/tests/test_conf.py +85 -0
  40. stapel_cdn-0.4.1/tests/test_file_exists_matrix.py +124 -0
  41. stapel_cdn-0.4.1/tests/test_forms.py +111 -0
  42. stapel_cdn-0.4.1/tests/test_functions.py +103 -0
  43. stapel_cdn-0.4.1/tests/test_gdpr_actions.py +157 -0
  44. stapel_cdn-0.4.1/tests/test_models.py +99 -0
  45. stapel_cdn-0.4.1/tests/test_public_api.py +70 -0
  46. stapel_cdn-0.4.1/tests/test_refs_sync.py +222 -0
  47. stapel_cdn-0.4.1/tests/test_serializer_seams.py +89 -0
  48. stapel_cdn-0.4.1/tests/test_serializers.py +313 -0
  49. stapel_cdn-0.4.1/tests/test_services.py +311 -0
  50. stapel_cdn-0.4.1/tests/test_signals.py +75 -0
  51. stapel_cdn-0.4.1/tests/test_tasks.py +207 -0
  52. stapel_cdn-0.4.1/tests/test_upload_endpoints.py +431 -0
  53. stapel_cdn-0.4.1/tests/test_upload_handlers.py +63 -0
  54. stapel_cdn-0.4.1/tests/test_views.py +400 -0
  55. stapel_cdn-0.4.1/tests/urls.py +5 -0
  56. stapel_cdn-0.4.1/upload_handlers.py +71 -0
  57. stapel_cdn-0.4.1/urls.py +25 -0
  58. stapel_cdn-0.4.1/validators.py +55 -0
  59. stapel_cdn-0.4.1/views.py +999 -0
  60. stapel_cdn-0.4.1/watermarks.py +59 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 usestapel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,58 @@
1
+ Metadata-Version: 2.4
2
+ Name: stapel-cdn
3
+ Version: 0.4.1
4
+ Summary: Media/CDN management Django app for the Stapel framework
5
+ License: MIT
6
+ Keywords: django,stapel,cdn,media,storage
7
+ Classifier: Framework :: Django
8
+ Classifier: Framework :: Django :: 5.2
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: stapel-core<0.4,>=0.3.0
15
+ Requires-Dist: Pillow>=9.0
16
+ Requires-Dist: celery>=5
17
+ Provides-Extra: s3
18
+ Requires-Dist: boto3>=1.34; extra == "s3"
19
+ Provides-Extra: images
20
+ Requires-Dist: pyvips>=2.2; extra == "images"
21
+ Provides-Extra: all
22
+ Requires-Dist: stapel-cdn[images,s3]; extra == "all"
23
+ Dynamic: license-file
24
+
25
+ # stapel-cdn
26
+
27
+ [![CI](https://github.com/usestapel/stapel-cdn/actions/workflows/ci.yml/badge.svg)](https://github.com/usestapel/stapel-cdn/actions/workflows/ci.yml)
28
+ [![codecov](https://codecov.io/gh/usestapel/stapel-cdn/graph/badge.svg)](https://codecov.io/gh/usestapel/stapel-cdn)
29
+
30
+ > Media management — image/video/file upload, processing, CDN ref tracking
31
+
32
+ Part of the [Stapel framework](https://github.com/usestapel) — composable Django apps for building production-grade platforms.
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ pip install stapel-cdn
38
+ ```
39
+
40
+ ## Quick start
41
+
42
+ ```python
43
+ # settings.py
44
+ INSTALLED_APPS = [
45
+ ...
46
+ 'stapel_cdn',
47
+ ]
48
+ ```
49
+
50
+ ## Bus events
51
+
52
+ ### Consumes
53
+ | `user.deleted` | [schema](schemas/consumes/user.deleted.json) |
54
+ | `user.deletion_initiated` | [schema](schemas/consumes/user.deletion_initiated.json) |
55
+
56
+ ## License
57
+
58
+ MIT — see [LICENSE](LICENSE)
@@ -0,0 +1,34 @@
1
+ # stapel-cdn
2
+
3
+ [![CI](https://github.com/usestapel/stapel-cdn/actions/workflows/ci.yml/badge.svg)](https://github.com/usestapel/stapel-cdn/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/gh/usestapel/stapel-cdn/graph/badge.svg)](https://codecov.io/gh/usestapel/stapel-cdn)
5
+
6
+ > Media management — image/video/file upload, processing, CDN ref tracking
7
+
8
+ Part of the [Stapel framework](https://github.com/usestapel) — composable Django apps for building production-grade platforms.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install stapel-cdn
14
+ ```
15
+
16
+ ## Quick start
17
+
18
+ ```python
19
+ # settings.py
20
+ INSTALLED_APPS = [
21
+ ...
22
+ 'stapel_cdn',
23
+ ]
24
+ ```
25
+
26
+ ## Bus events
27
+
28
+ ### Consumes
29
+ | `user.deleted` | [schema](schemas/consumes/user.deleted.json) |
30
+ | `user.deletion_initiated` | [schema](schemas/consumes/user.deletion_initiated.json) |
31
+
32
+ ## License
33
+
34
+ MIT — see [LICENSE](LICENSE)
@@ -0,0 +1,47 @@
1
+ """CDN app for stapel-cdn service.
2
+
3
+ Public API (lazily exported, PEP 562 — importing this package never pulls
4
+ in Django or requires configured settings):
5
+
6
+ - ``cdn_settings`` — resolved app settings (``stapel_cdn.conf``).
7
+ - ``media_exists`` — comm function: check whether a media ref resolves to a
8
+ stored CDN asset (``stapel_cdn.functions``).
9
+ - ``refs_sync`` — comm function: sync entity → media reference tracking
10
+ (``stapel_cdn.functions``).
11
+ - ``validate_image_file`` — upload validator: extension allowlist, Pillow
12
+ decode check, decompression-bomb cap (``stapel_cdn.validators``).
13
+ - ``text_watermark`` — built-in reference watermark engine for the
14
+ ``STAPEL_CDN["WATERMARK"]`` seam (``stapel_cdn.watermarks``).
15
+ """
16
+
17
+ __all__ = [
18
+ "cdn_settings",
19
+ "media_exists",
20
+ "refs_sync",
21
+ "text_watermark",
22
+ "validate_image_file",
23
+ ]
24
+
25
+ # name → submodule that defines it. Resolution is deferred until first
26
+ # attribute access so that `import stapel_cdn` stays Django-free.
27
+ _LAZY_EXPORTS = {
28
+ "cdn_settings": ".conf",
29
+ "media_exists": ".functions",
30
+ "refs_sync": ".functions",
31
+ "text_watermark": ".watermarks",
32
+ "validate_image_file": ".validators",
33
+ }
34
+
35
+
36
+ def __getattr__(name):
37
+ if name in _LAZY_EXPORTS:
38
+ from importlib import import_module
39
+
40
+ value = getattr(import_module(_LAZY_EXPORTS[name], __name__), name)
41
+ globals()[name] = value # cache for subsequent lookups
42
+ return value
43
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
44
+
45
+
46
+ def __dir__():
47
+ return sorted(set(globals()) | set(__all__))
@@ -0,0 +1,23 @@
1
+ """Action subscriptions of the cdn module.
2
+
3
+ Handlers must be idempotent: delivery is at-least-once (outbox retries,
4
+ broker redelivery).
5
+ """
6
+ import logging
7
+
8
+ from stapel_core.comm import on_action
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ @on_action("user.deleted")
14
+ def handle_user_deleted(event):
15
+ """Erase this module's PII when an account deletion is executed."""
16
+ from .gdpr import CDNGDPRProvider
17
+
18
+ user_id = event.payload.get("user_id")
19
+ if not user_id:
20
+ logger.error("user.deleted event without user_id: %s", event.event_id)
21
+ return
22
+ CDNGDPRProvider().delete(user_id)
23
+ logger.info("cdn data erased for deleted user %s", user_id)