django-nativemojo 0.1.10__py3-none-any.whl → 0.1.16__py3-none-any.whl
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.
- django_nativemojo-0.1.16.dist-info/METADATA +138 -0
- django_nativemojo-0.1.16.dist-info/RECORD +302 -0
- mojo/__init__.py +1 -1
- mojo/apps/account/management/__init__.py +5 -0
- mojo/apps/account/management/commands/__init__.py +6 -0
- mojo/apps/account/management/commands/serializer_admin.py +651 -0
- mojo/apps/account/migrations/0004_user_avatar.py +20 -0
- mojo/apps/account/migrations/0005_group_last_activity.py +18 -0
- mojo/apps/account/migrations/0006_add_device_tracking_models.py +72 -0
- mojo/apps/account/migrations/0007_delete_userdevicelocation.py +16 -0
- mojo/apps/account/migrations/0008_userdevicelocation.py +33 -0
- mojo/apps/account/migrations/0009_geolocatedip_subnet.py +18 -0
- mojo/apps/account/migrations/0010_group_avatar.py +20 -0
- mojo/apps/account/migrations/0011_user_org_registereddevice_pushconfig_and_more.py +118 -0
- mojo/apps/account/migrations/0012_remove_pushconfig_apns_key_file_and_more.py +21 -0
- mojo/apps/account/migrations/0013_pushconfig_test_mode_alter_pushconfig_apns_enabled_and_more.py +28 -0
- mojo/apps/account/migrations/0014_notificationdelivery_data_payload_and_more.py +48 -0
- mojo/apps/account/models/__init__.py +2 -0
- mojo/apps/account/models/device.py +281 -0
- mojo/apps/account/models/group.py +319 -15
- mojo/apps/account/models/member.py +29 -5
- mojo/apps/account/models/push/__init__.py +4 -0
- mojo/apps/account/models/push/config.py +112 -0
- mojo/apps/account/models/push/delivery.py +93 -0
- mojo/apps/account/models/push/device.py +66 -0
- mojo/apps/account/models/push/template.py +99 -0
- mojo/apps/account/models/user.py +369 -19
- mojo/apps/account/rest/__init__.py +2 -0
- mojo/apps/account/rest/device.py +39 -0
- mojo/apps/account/rest/group.py +9 -0
- mojo/apps/account/rest/push.py +187 -0
- mojo/apps/account/rest/user.py +100 -6
- mojo/apps/account/services/__init__.py +1 -0
- mojo/apps/account/services/push.py +363 -0
- mojo/apps/aws/migrations/0001_initial.py +206 -0
- mojo/apps/aws/migrations/0002_emaildomain_can_recv_emaildomain_can_send_and_more.py +28 -0
- mojo/apps/aws/migrations/0003_mailbox_is_domain_default_mailbox_is_system_default_and_more.py +31 -0
- mojo/apps/aws/migrations/0004_s3bucket.py +39 -0
- mojo/apps/aws/migrations/0005_alter_emaildomain_region_delete_s3bucket.py +21 -0
- mojo/apps/aws/models/__init__.py +19 -0
- mojo/apps/aws/models/email_attachment.py +99 -0
- mojo/apps/aws/models/email_domain.py +218 -0
- mojo/apps/aws/models/email_template.py +132 -0
- mojo/apps/aws/models/incoming_email.py +197 -0
- mojo/apps/aws/models/mailbox.py +288 -0
- mojo/apps/aws/models/sent_message.py +175 -0
- mojo/apps/aws/rest/__init__.py +7 -0
- mojo/apps/aws/rest/email.py +33 -0
- mojo/apps/aws/rest/email_ops.py +183 -0
- mojo/apps/aws/rest/messages.py +32 -0
- mojo/apps/aws/rest/s3.py +64 -0
- mojo/apps/aws/rest/send.py +101 -0
- mojo/apps/aws/rest/sns.py +403 -0
- mojo/apps/aws/rest/templates.py +19 -0
- mojo/apps/aws/services/__init__.py +32 -0
- mojo/apps/aws/services/email.py +390 -0
- mojo/apps/aws/services/email_ops.py +548 -0
- mojo/apps/docit/__init__.py +6 -0
- mojo/apps/docit/markdown_plugins/syntax_highlight.py +25 -0
- mojo/apps/docit/markdown_plugins/toc.py +12 -0
- mojo/apps/docit/migrations/0001_initial.py +113 -0
- mojo/apps/docit/migrations/0002_alter_book_modified_by_alter_page_modified_by.py +26 -0
- mojo/apps/docit/migrations/0003_alter_book_group.py +20 -0
- mojo/apps/docit/models/__init__.py +17 -0
- mojo/apps/docit/models/asset.py +231 -0
- mojo/apps/docit/models/book.py +227 -0
- mojo/apps/docit/models/page.py +319 -0
- mojo/apps/docit/models/page_revision.py +203 -0
- mojo/apps/docit/rest/__init__.py +10 -0
- mojo/apps/docit/rest/asset.py +17 -0
- mojo/apps/docit/rest/book.py +22 -0
- mojo/apps/docit/rest/page.py +22 -0
- mojo/apps/docit/rest/page_revision.py +17 -0
- mojo/apps/docit/services/__init__.py +11 -0
- mojo/apps/docit/services/docit.py +315 -0
- mojo/apps/docit/services/markdown.py +44 -0
- mojo/apps/fileman/README.md +8 -8
- mojo/apps/fileman/backends/base.py +76 -70
- mojo/apps/fileman/backends/filesystem.py +86 -86
- mojo/apps/fileman/backends/s3.py +409 -108
- mojo/apps/fileman/migrations/0001_initial.py +106 -0
- mojo/apps/fileman/migrations/0002_filemanager_parent_alter_filemanager_max_file_size.py +24 -0
- mojo/apps/fileman/migrations/0003_remove_file_fileman_fil_upload__c4bc35_idx_and_more.py +25 -0
- mojo/apps/fileman/migrations/0004_remove_file_original_filename_and_more.py +39 -0
- mojo/apps/fileman/migrations/0005_alter_file_upload_token.py +18 -0
- mojo/apps/fileman/migrations/0006_file_download_url_filemanager_forever_urls.py +23 -0
- mojo/apps/fileman/migrations/0007_remove_filemanager_forever_urls_and_more.py +22 -0
- mojo/apps/fileman/migrations/0008_file_category.py +18 -0
- mojo/apps/fileman/migrations/0009_rename_file_path_file_storage_file_path.py +18 -0
- mojo/apps/fileman/migrations/0010_filerendition.py +33 -0
- mojo/apps/fileman/migrations/0011_alter_filerendition_original_file.py +19 -0
- mojo/apps/fileman/models/__init__.py +1 -5
- mojo/apps/fileman/models/file.py +240 -58
- mojo/apps/fileman/models/manager.py +427 -31
- mojo/apps/fileman/models/rendition.py +118 -0
- mojo/apps/fileman/renderer/__init__.py +111 -0
- mojo/apps/fileman/renderer/audio.py +403 -0
- mojo/apps/fileman/renderer/base.py +205 -0
- mojo/apps/fileman/renderer/document.py +404 -0
- mojo/apps/fileman/renderer/image.py +222 -0
- mojo/apps/fileman/renderer/utils.py +297 -0
- mojo/apps/fileman/renderer/video.py +304 -0
- mojo/apps/fileman/rest/__init__.py +1 -18
- mojo/apps/fileman/rest/upload.py +22 -32
- mojo/apps/fileman/signals.py +58 -0
- mojo/apps/fileman/tasks.py +254 -0
- mojo/apps/fileman/utils/__init__.py +40 -16
- mojo/apps/incident/migrations/0005_incidenthistory.py +39 -0
- mojo/apps/incident/migrations/0006_alter_incident_state.py +18 -0
- mojo/apps/incident/migrations/0007_event_uid.py +18 -0
- mojo/apps/incident/migrations/0008_ticket_ticketnote.py +55 -0
- mojo/apps/incident/migrations/0009_incident_status.py +18 -0
- mojo/apps/incident/migrations/0010_event_country_code.py +18 -0
- mojo/apps/incident/migrations/0011_incident_country_code.py +18 -0
- mojo/apps/incident/migrations/0012_alter_incident_status.py +18 -0
- mojo/apps/incident/models/__init__.py +2 -0
- mojo/apps/incident/models/event.py +35 -0
- mojo/apps/incident/models/history.py +36 -0
- mojo/apps/incident/models/incident.py +3 -1
- mojo/apps/incident/models/ticket.py +62 -0
- mojo/apps/incident/reporter.py +21 -1
- mojo/apps/incident/rest/__init__.py +1 -0
- mojo/apps/incident/rest/event.py +7 -1
- mojo/apps/incident/rest/ticket.py +43 -0
- mojo/apps/jobs/__init__.py +489 -0
- mojo/apps/jobs/adapters.py +24 -0
- mojo/apps/jobs/cli.py +616 -0
- mojo/apps/jobs/daemon.py +370 -0
- mojo/apps/jobs/examples/sample_jobs.py +376 -0
- mojo/apps/jobs/examples/webhook_examples.py +203 -0
- mojo/apps/jobs/handlers/__init__.py +5 -0
- mojo/apps/jobs/handlers/webhook.py +317 -0
- mojo/apps/jobs/job_engine.py +734 -0
- mojo/apps/jobs/keys.py +203 -0
- mojo/apps/jobs/local_queue.py +363 -0
- mojo/apps/jobs/management/__init__.py +3 -0
- mojo/apps/jobs/management/commands/__init__.py +3 -0
- mojo/apps/jobs/manager.py +1327 -0
- mojo/apps/jobs/migrations/0001_initial.py +97 -0
- mojo/apps/jobs/migrations/0002_alter_job_max_retries_joblog.py +39 -0
- mojo/apps/jobs/models/__init__.py +6 -0
- mojo/apps/jobs/models/job.py +441 -0
- mojo/apps/jobs/rest/__init__.py +2 -0
- mojo/apps/jobs/rest/control.py +466 -0
- mojo/apps/jobs/rest/jobs.py +421 -0
- mojo/apps/jobs/scheduler.py +571 -0
- mojo/apps/jobs/services/__init__.py +6 -0
- mojo/apps/jobs/services/job_actions.py +465 -0
- mojo/apps/jobs/settings.py +209 -0
- mojo/apps/logit/migrations/0004_alter_log_level.py +18 -0
- mojo/apps/logit/models/log.py +7 -1
- mojo/apps/metrics/__init__.py +8 -1
- mojo/apps/metrics/redis_metrics.py +198 -0
- mojo/apps/metrics/rest/__init__.py +3 -0
- mojo/apps/metrics/rest/categories.py +266 -0
- mojo/apps/metrics/rest/helpers.py +48 -0
- mojo/apps/metrics/rest/permissions.py +99 -0
- mojo/apps/metrics/rest/values.py +277 -0
- mojo/apps/metrics/utils.py +19 -2
- mojo/decorators/auth.py +6 -1
- mojo/decorators/http.py +47 -3
- mojo/helpers/aws/__init__.py +45 -0
- mojo/helpers/aws/ec2.py +804 -0
- mojo/helpers/aws/iam.py +748 -0
- mojo/helpers/aws/inbound_email.py +309 -0
- mojo/helpers/aws/kms.py +413 -0
- mojo/helpers/aws/s3.py +451 -11
- mojo/helpers/aws/ses.py +483 -0
- mojo/helpers/aws/ses_domain.py +959 -0
- mojo/helpers/aws/sns.py +461 -0
- mojo/helpers/crypto/__init__.py +1 -1
- mojo/helpers/crypto/utils.py +15 -0
- mojo/helpers/dates.py +18 -0
- mojo/helpers/location/__init__.py +2 -0
- mojo/helpers/location/countries.py +262 -0
- mojo/helpers/location/geolocation.py +196 -0
- mojo/helpers/logit.py +37 -0
- mojo/helpers/redis/__init__.py +2 -0
- mojo/helpers/redis/adapter.py +606 -0
- mojo/helpers/redis/client.py +48 -0
- mojo/helpers/redis/pool.py +225 -0
- mojo/helpers/request.py +8 -0
- mojo/helpers/response.py +14 -2
- mojo/helpers/settings/__init__.py +2 -0
- mojo/helpers/{settings.py → settings/helper.py} +1 -37
- mojo/helpers/settings/parser.py +132 -0
- mojo/middleware/auth.py +1 -1
- mojo/middleware/cors.py +40 -0
- mojo/middleware/logging.py +131 -12
- mojo/middleware/mojo.py +10 -0
- mojo/models/rest.py +494 -65
- mojo/models/secrets.py +98 -3
- mojo/serializers/__init__.py +106 -0
- mojo/serializers/core/__init__.py +90 -0
- mojo/serializers/core/cache/__init__.py +121 -0
- mojo/serializers/core/cache/backends.py +518 -0
- mojo/serializers/core/cache/base.py +102 -0
- mojo/serializers/core/cache/disabled.py +181 -0
- mojo/serializers/core/cache/memory.py +287 -0
- mojo/serializers/core/cache/redis.py +533 -0
- mojo/serializers/core/cache/utils.py +454 -0
- mojo/serializers/core/manager.py +550 -0
- mojo/serializers/core/serializer.py +475 -0
- mojo/serializers/examples/settings.py +322 -0
- mojo/serializers/formats/csv.py +393 -0
- mojo/serializers/formats/localizers.py +509 -0
- mojo/serializers/{models.py → simple.py} +38 -15
- mojo/serializers/suggested_improvements.md +388 -0
- testit/client.py +1 -1
- testit/helpers.py +35 -4
- testit/runner.py +23 -6
- django_nativemojo-0.1.10.dist-info/METADATA +0 -96
- django_nativemojo-0.1.10.dist-info/RECORD +0 -194
- mojo/apps/metrics/rest/db.py +0 -0
- mojo/apps/notify/README.md +0 -91
- mojo/apps/notify/README_NOTIFICATIONS.md +0 -566
- mojo/apps/notify/admin.py +0 -52
- mojo/apps/notify/handlers/example_handlers.py +0 -516
- mojo/apps/notify/handlers/ses/__init__.py +0 -25
- mojo/apps/notify/handlers/ses/bounce.py +0 -0
- mojo/apps/notify/handlers/ses/complaint.py +0 -25
- mojo/apps/notify/handlers/ses/message.py +0 -86
- mojo/apps/notify/management/commands/__init__.py +0 -1
- mojo/apps/notify/management/commands/process_notifications.py +0 -370
- mojo/apps/notify/mod +0 -0
- mojo/apps/notify/models/__init__.py +0 -12
- mojo/apps/notify/models/account.py +0 -128
- mojo/apps/notify/models/attachment.py +0 -24
- mojo/apps/notify/models/bounce.py +0 -68
- mojo/apps/notify/models/complaint.py +0 -40
- mojo/apps/notify/models/inbox.py +0 -113
- mojo/apps/notify/models/inbox_message.py +0 -173
- mojo/apps/notify/models/outbox.py +0 -129
- mojo/apps/notify/models/outbox_message.py +0 -288
- mojo/apps/notify/models/template.py +0 -30
- mojo/apps/notify/providers/aws.py +0 -73
- mojo/apps/notify/rest/ses.py +0 -0
- mojo/apps/notify/utils/__init__.py +0 -2
- mojo/apps/notify/utils/notifications.py +0 -404
- mojo/apps/notify/utils/parsing.py +0 -202
- mojo/apps/notify/utils/render.py +0 -144
- mojo/apps/tasks/README.md +0 -118
- mojo/apps/tasks/__init__.py +0 -11
- mojo/apps/tasks/manager.py +0 -489
- mojo/apps/tasks/rest/__init__.py +0 -2
- mojo/apps/tasks/rest/hooks.py +0 -0
- mojo/apps/tasks/rest/tasks.py +0 -62
- mojo/apps/tasks/runner.py +0 -174
- mojo/apps/tasks/tq_handlers.py +0 -14
- mojo/helpers/aws/setup_email.py +0 -0
- mojo/helpers/redis.py +0 -10
- mojo/models/meta.py +0 -262
- mojo/ws4redis/README.md +0 -174
- mojo/ws4redis/__init__.py +0 -2
- mojo/ws4redis/client.py +0 -283
- mojo/ws4redis/connection.py +0 -327
- mojo/ws4redis/exceptions.py +0 -32
- mojo/ws4redis/redis.py +0 -183
- mojo/ws4redis/servers/base.py +0 -86
- mojo/ws4redis/servers/django.py +0 -171
- mojo/ws4redis/servers/uwsgi.py +0 -63
- mojo/ws4redis/settings.py +0 -45
- mojo/ws4redis/utf8validator.py +0 -128
- mojo/ws4redis/websocket.py +0 -403
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.16.dist-info}/LICENSE +0 -0
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.16.dist-info}/NOTICE +0 -0
- {django_nativemojo-0.1.10.dist-info → django_nativemojo-0.1.16.dist-info}/WHEEL +0 -0
- /mojo/apps/{notify → aws}/__init__.py +0 -0
- /mojo/apps/{notify/handlers → aws/migrations}/__init__.py +0 -0
- /mojo/apps/{notify/management → docit/markdown_plugins}/__init__.py +0 -0
- /mojo/apps/{notify/providers → docit/migrations}/__init__.py +0 -0
- /mojo/apps/{notify/rest → fileman/migrations}/__init__.py +0 -0
- /mojo/{ws4redis/servers → apps/jobs/examples}/__init__.py +0 -0
- /mojo/apps/{fileman/models/render.py → jobs/migrations/__init__.py} +0 -0
- /mojo/{serializers → rest}/openapi.py +0 -0
- /mojo/{apps/fileman/rest/__init__ → serializers/formats/__init__.py} +0 -0
mojo/models/secrets.py
CHANGED
@@ -11,12 +11,18 @@ class MojoSecrets(models.Model):
|
|
11
11
|
|
12
12
|
mojo_secrets = models.TextField(blank=True, null=True, default=None)
|
13
13
|
_exposed_secrets = None
|
14
|
+
_secrets_changed = False
|
14
15
|
|
15
16
|
def set_secrets(self, value):
|
17
|
+
self.debug("Setting secrets", repr(value))
|
18
|
+
if isinstance(value, str):
|
19
|
+
value = objict.from_json(value)
|
16
20
|
self._exposed_secrets = merge_dicts(self.secrets, value)
|
21
|
+
self._secrets_changed = True
|
17
22
|
|
18
23
|
def set_secret(self, key, value):
|
19
24
|
self.secrets[key] = value
|
25
|
+
self._secrets_changed = True
|
20
26
|
|
21
27
|
def get_secret(self, key, default=None):
|
22
28
|
return self.secrets.get(key, default)
|
@@ -24,6 +30,7 @@ class MojoSecrets(models.Model):
|
|
24
30
|
def clear_secrets(self):
|
25
31
|
self.mojo_secrets = None
|
26
32
|
self._exposed_secrets = objict()
|
33
|
+
self._secrets_changed = True
|
27
34
|
|
28
35
|
@property
|
29
36
|
def secrets(self):
|
@@ -44,10 +51,79 @@ class MojoSecrets(models.Model):
|
|
44
51
|
return salt
|
45
52
|
|
46
53
|
def save_secrets(self):
|
47
|
-
if self.
|
48
|
-
|
54
|
+
if self._secrets_changed:
|
55
|
+
if self._exposed_secrets:
|
56
|
+
self.mojo_secrets = crypto.encrypt( self._exposed_secrets, self._get_secrets_password())
|
57
|
+
else:
|
58
|
+
self.mojo_secrets = None
|
59
|
+
self._secrets_changed = False
|
60
|
+
|
61
|
+
def save(self, *args, **kwargs):
|
62
|
+
if self.pk is not None:
|
63
|
+
self.save_secrets()
|
64
|
+
super().save(*args, **kwargs)
|
49
65
|
else:
|
50
|
-
|
66
|
+
super().save(*args, **kwargs)
|
67
|
+
self.save_secrets()
|
68
|
+
super().save()
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
class KSMSecrets(models.Model):
|
73
|
+
"""Base model class for adding secrets to a model using AWS KMS (envelope encryption)."""
|
74
|
+
class Meta:
|
75
|
+
abstract = True
|
76
|
+
|
77
|
+
mojo_secrets = models.TextField(blank=True, null=True, default=None)
|
78
|
+
_exposed_secrets = None
|
79
|
+
_secrets_changed = False
|
80
|
+
_kms_cache = {}
|
81
|
+
|
82
|
+
def set_secrets(self, value):
|
83
|
+
self.debug("Setting secrets", repr(value))
|
84
|
+
if isinstance(value, str):
|
85
|
+
value = objict.from_json(value)
|
86
|
+
self._exposed_secrets = merge_dicts(self.secrets, value)
|
87
|
+
self._secrets_changed = True
|
88
|
+
|
89
|
+
def set_secret(self, key, value):
|
90
|
+
self.secrets[key] = value
|
91
|
+
self._secrets_changed = True
|
92
|
+
|
93
|
+
def get_secret(self, key, default=None):
|
94
|
+
return self.secrets.get(key, default)
|
95
|
+
|
96
|
+
def clear_secrets(self):
|
97
|
+
self.mojo_secrets = None
|
98
|
+
self._exposed_secrets = objict()
|
99
|
+
self._secrets_changed = True
|
100
|
+
|
101
|
+
@property
|
102
|
+
def secrets(self):
|
103
|
+
if self._exposed_secrets is not None:
|
104
|
+
return self._exposed_secrets
|
105
|
+
if self.mojo_secrets is None or self.pk is None:
|
106
|
+
self._exposed_secrets = objict()
|
107
|
+
return self._exposed_secrets
|
108
|
+
if self._exposed_secrets is None:
|
109
|
+
try:
|
110
|
+
data = self._get_kms().decrypt_dict_field(self._kms_context(), self.mojo_secrets)
|
111
|
+
# convert to objict mapping
|
112
|
+
self._exposed_secrets = objict.from_dict(data)
|
113
|
+
except Exception:
|
114
|
+
# On failure, expose empty to avoid leaking details
|
115
|
+
self._exposed_secrets = objict()
|
116
|
+
return self._exposed_secrets
|
117
|
+
|
118
|
+
def save_secrets(self):
|
119
|
+
if self._secrets_changed:
|
120
|
+
if self._exposed_secrets:
|
121
|
+
# objict behaves like a dict; KMSHelper accepts dict
|
122
|
+
blob = self._get_kms().encrypt_field(self._kms_context(), self._exposed_secrets)
|
123
|
+
self.mojo_secrets = blob
|
124
|
+
else:
|
125
|
+
self.mojo_secrets = None
|
126
|
+
self._secrets_changed = False
|
51
127
|
|
52
128
|
def save(self, *args, **kwargs):
|
53
129
|
if self.pk is not None:
|
@@ -57,3 +133,22 @@ class MojoSecrets(models.Model):
|
|
57
133
|
super().save(*args, **kwargs)
|
58
134
|
self.save_secrets()
|
59
135
|
super().save()
|
136
|
+
|
137
|
+
@classmethod
|
138
|
+
def _get_kms(cls):
|
139
|
+
kms_key_id = settings.get("KMS_KEY_ID", None)
|
140
|
+
region = settings.get("AWS_REGION", settings.get("AWS_DEFAULT_REGION", "us-east-1"))
|
141
|
+
if not kms_key_id:
|
142
|
+
raise RuntimeError("KMS_KEY_ID must be configured to use KSMSecrets")
|
143
|
+
cache_key = (kms_key_id, region)
|
144
|
+
helper = cls._kms_cache.get(cache_key)
|
145
|
+
if helper is None:
|
146
|
+
from mojo.helpers.aws.kms import KMSHelper
|
147
|
+
helper = KMSHelper(kms_key_id=kms_key_id, region_name=region)
|
148
|
+
cls._kms_cache[cache_key] = helper
|
149
|
+
return helper
|
150
|
+
|
151
|
+
def _kms_context(self):
|
152
|
+
# Bind to app_label.Model.<pk>.mojo_secrets for contextual integrity
|
153
|
+
app_label = getattr(self._meta, "app_label", self.__class__.__module__.split(".")[0])
|
154
|
+
return f"{app_label}.{self.__class__.__name__}.{self.pk}.mojo_secrets"
|
mojo/serializers/__init__.py
CHANGED
@@ -0,0 +1,106 @@
|
|
1
|
+
"""
|
2
|
+
Django-MOJO Serializers Package
|
3
|
+
|
4
|
+
Provides high-performance serialization for Django models with RestMeta.GRAPHS support.
|
5
|
+
Includes multiple serializer backends optimized for different use cases:
|
6
|
+
|
7
|
+
- OptimizedGraphSerializer: Ultra-fast with intelligent caching (default)
|
8
|
+
- GraphSerializer: Simple and reliable fallback
|
9
|
+
- AdvancedGraphSerializer: Feature-rich with multiple format support
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
from mojo.serializers import serialize, to_json, to_response
|
13
|
+
|
14
|
+
# Quick serialization
|
15
|
+
data = serialize(instance, graph="detail")
|
16
|
+
json_str = to_json(queryset, graph="list")
|
17
|
+
response = to_response(instance, request, graph="default")
|
18
|
+
|
19
|
+
# Direct serializer access
|
20
|
+
from mojo.serializers import OptimizedGraphSerializer
|
21
|
+
serializer = OptimizedGraphSerializer(instance, graph="detail")
|
22
|
+
data = serializer.serialize()
|
23
|
+
"""
|
24
|
+
|
25
|
+
# Core serializer classes
|
26
|
+
from .simple import GraphSerializer
|
27
|
+
|
28
|
+
# New optimized core system (default)
|
29
|
+
from .core import (
|
30
|
+
OptimizedGraphSerializer,
|
31
|
+
SerializerManager,
|
32
|
+
get_serializer_manager,
|
33
|
+
register_serializer,
|
34
|
+
set_default_serializer,
|
35
|
+
serialize,
|
36
|
+
to_json,
|
37
|
+
to_response,
|
38
|
+
get_performance_stats,
|
39
|
+
clear_serializer_caches,
|
40
|
+
benchmark_serializers,
|
41
|
+
HAS_UJSON,
|
42
|
+
UJSON_VERSION
|
43
|
+
)
|
44
|
+
|
45
|
+
# Advanced serializer (optional - may not be available)
|
46
|
+
try:
|
47
|
+
from .advanced import AdvancedGraphSerializer
|
48
|
+
except ImportError:
|
49
|
+
AdvancedGraphSerializer = None
|
50
|
+
|
51
|
+
# Version and metadata
|
52
|
+
__version__ = "2.0.0"
|
53
|
+
__author__ = "Django-MOJO Team"
|
54
|
+
|
55
|
+
# Default exports
|
56
|
+
__all__ = [
|
57
|
+
# Core serializer classes
|
58
|
+
'GraphSerializer',
|
59
|
+
'OptimizedGraphSerializer',
|
60
|
+
'AdvancedGraphSerializer',
|
61
|
+
|
62
|
+
# Manager
|
63
|
+
'SerializerManager',
|
64
|
+
'get_serializer_manager',
|
65
|
+
|
66
|
+
# Registration functions
|
67
|
+
'register_serializer',
|
68
|
+
'set_default_serializer',
|
69
|
+
|
70
|
+
# Convenience functions
|
71
|
+
'serialize',
|
72
|
+
'to_json',
|
73
|
+
'to_response',
|
74
|
+
|
75
|
+
# Performance monitoring
|
76
|
+
'get_performance_stats',
|
77
|
+
'clear_serializer_caches',
|
78
|
+
'benchmark_serializers',
|
79
|
+
|
80
|
+
# Performance info
|
81
|
+
'HAS_UJSON',
|
82
|
+
'UJSON_VERSION',
|
83
|
+
]
|
84
|
+
|
85
|
+
# Initialize default manager on import
|
86
|
+
_manager = get_serializer_manager()
|
87
|
+
|
88
|
+
# Convenience shortcuts at package level
|
89
|
+
def get_serializer(instance, graph="default", many=None, serializer_type=None, **kwargs):
|
90
|
+
"""Get configured serializer instance."""
|
91
|
+
return _manager.get_serializer(instance, graph, many, serializer_type, **kwargs)
|
92
|
+
|
93
|
+
def list_serializers():
|
94
|
+
"""List all registered serializers."""
|
95
|
+
return _manager.registry.list_serializers()
|
96
|
+
|
97
|
+
def get_default_serializer():
|
98
|
+
"""Get the current default serializer name."""
|
99
|
+
return _manager.registry.get_default()
|
100
|
+
|
101
|
+
# Add shortcuts to exports
|
102
|
+
__all__.extend([
|
103
|
+
'get_serializer',
|
104
|
+
'list_serializers',
|
105
|
+
'get_default_serializer'
|
106
|
+
])
|
@@ -0,0 +1,90 @@
|
|
1
|
+
"""
|
2
|
+
Django-MOJO Core Serializers
|
3
|
+
|
4
|
+
High-performance serialization system with intelligent caching and RestMeta.GRAPHS support.
|
5
|
+
This is the optimized serializer implementation with pluggable cache backends.
|
6
|
+
|
7
|
+
Main Components:
|
8
|
+
- OptimizedGraphSerializer: Ultra-fast serializer with smart caching
|
9
|
+
- SerializerManager: Unified interface for all serializer backends
|
10
|
+
- Cache backends: Memory and Redis-based caching systems
|
11
|
+
|
12
|
+
Usage:
|
13
|
+
from mojo.serializers.core import OptimizedGraphSerializer, SerializerManager
|
14
|
+
|
15
|
+
# Direct usage
|
16
|
+
serializer = OptimizedGraphSerializer(instance, graph="detail")
|
17
|
+
data = serializer.serialize()
|
18
|
+
|
19
|
+
# Via manager
|
20
|
+
manager = SerializerManager()
|
21
|
+
serializer = manager.get_serializer(instance, graph="list")
|
22
|
+
"""
|
23
|
+
|
24
|
+
# Import core components
|
25
|
+
from .serializer import OptimizedGraphSerializer
|
26
|
+
from .manager import (
|
27
|
+
SerializerManager,
|
28
|
+
get_serializer_manager,
|
29
|
+
register_serializer,
|
30
|
+
set_default_serializer,
|
31
|
+
serialize,
|
32
|
+
to_json,
|
33
|
+
to_response,
|
34
|
+
get_performance_stats,
|
35
|
+
clear_serializer_caches,
|
36
|
+
benchmark_serializers,
|
37
|
+
list_serializers,
|
38
|
+
HAS_UJSON,
|
39
|
+
UJSON_VERSION
|
40
|
+
)
|
41
|
+
|
42
|
+
# Import cache system
|
43
|
+
from .cache import (
|
44
|
+
get_cache_backend,
|
45
|
+
get_cache_key,
|
46
|
+
get_model_cache_ttl,
|
47
|
+
get_cache_stats,
|
48
|
+
clear_all_caches,
|
49
|
+
HAS_UJSON,
|
50
|
+
UJSON_VERSION
|
51
|
+
)
|
52
|
+
|
53
|
+
# Core serializer exports
|
54
|
+
__all__ = [
|
55
|
+
# Main serializer
|
56
|
+
'OptimizedGraphSerializer',
|
57
|
+
|
58
|
+
# Manager
|
59
|
+
'SerializerManager',
|
60
|
+
'get_serializer_manager',
|
61
|
+
|
62
|
+
# Registration functions
|
63
|
+
'register_serializer',
|
64
|
+
'set_default_serializer',
|
65
|
+
|
66
|
+
# Convenience functions
|
67
|
+
'serialize',
|
68
|
+
'to_json',
|
69
|
+
'to_response',
|
70
|
+
|
71
|
+
# Performance monitoring
|
72
|
+
'get_performance_stats',
|
73
|
+
'clear_serializer_caches',
|
74
|
+
'benchmark_serializers',
|
75
|
+
'list_serializers',
|
76
|
+
|
77
|
+
# Cache system
|
78
|
+
'get_cache_backend',
|
79
|
+
'get_cache_key',
|
80
|
+
'get_model_cache_ttl',
|
81
|
+
'get_cache_stats',
|
82
|
+
'clear_all_caches',
|
83
|
+
|
84
|
+
# Performance info
|
85
|
+
'HAS_UJSON',
|
86
|
+
'UJSON_VERSION',
|
87
|
+
]
|
88
|
+
|
89
|
+
# Version info
|
90
|
+
__version__ = "1.0.0"
|
@@ -0,0 +1,121 @@
|
|
1
|
+
"""
|
2
|
+
Django-MOJO Cache System for Serializers
|
3
|
+
|
4
|
+
Provides pluggable cache backends for high-performance serialization with intelligent
|
5
|
+
TTL management based on RestMeta.GRAPHS configuration.
|
6
|
+
|
7
|
+
Supported Backends:
|
8
|
+
- MemoryCacheBackend: In-process LRU cache with TTL support
|
9
|
+
- RedisCacheBackend: Distributed Redis-based caching (future)
|
10
|
+
- DisabledCacheBackend: No-op cache for development/testing
|
11
|
+
|
12
|
+
Key Features:
|
13
|
+
- RestMeta.cache_ttl configuration per model/graph
|
14
|
+
- LRU eviction with configurable size limits
|
15
|
+
- JSON serialization for Redis compatibility
|
16
|
+
- Thread-safe operations
|
17
|
+
- Safe defaults (cache_ttl=0 means no caching)
|
18
|
+
|
19
|
+
Usage:
|
20
|
+
from mojo.serializers.core.cache import get_cache_backend
|
21
|
+
|
22
|
+
cache = get_cache_backend()
|
23
|
+
|
24
|
+
# Get cached item (returns None if not found/expired)
|
25
|
+
data = cache.get("Event_123_default")
|
26
|
+
|
27
|
+
# Set with TTL from RestMeta configuration
|
28
|
+
cache.set("Event_123_default", serialized_data, ttl=300)
|
29
|
+
|
30
|
+
Configuration:
|
31
|
+
MOJO_SERIALIZER_CACHE = {
|
32
|
+
'backend': 'memory', # 'memory', 'redis', 'disabled'
|
33
|
+
'memory': {
|
34
|
+
'max_size': 5000,
|
35
|
+
'enable_stats': True
|
36
|
+
},
|
37
|
+
'redis': { # Future implementation
|
38
|
+
'host': 'localhost',
|
39
|
+
'port': 6379,
|
40
|
+
'key_prefix': 'mojo:serializer:'
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
RestMeta Configuration:
|
45
|
+
class MyModel(MojoModel):
|
46
|
+
class RestMeta:
|
47
|
+
GRAPHS = {
|
48
|
+
"default": {
|
49
|
+
"fields": ["id", "name"],
|
50
|
+
"cache_ttl": 300 # 5 minutes
|
51
|
+
},
|
52
|
+
"realtime": {
|
53
|
+
"fields": ["id", "status"],
|
54
|
+
"cache_ttl": 0 # No caching (default)
|
55
|
+
}
|
56
|
+
}
|
57
|
+
"""
|
58
|
+
|
59
|
+
from .base import CacheBackend
|
60
|
+
from .memory import MemoryCacheBackend
|
61
|
+
from .redis import RedisCacheBackend
|
62
|
+
from .disabled import DisabledCacheBackend
|
63
|
+
from .backends import (
|
64
|
+
get_cache_backend,
|
65
|
+
create_cache_backend,
|
66
|
+
reset_cache_backend,
|
67
|
+
get_available_backends,
|
68
|
+
test_backend_connectivity,
|
69
|
+
get_cache_health,
|
70
|
+
validate_cache_config
|
71
|
+
)
|
72
|
+
|
73
|
+
from .utils import (
|
74
|
+
get_cache_key,
|
75
|
+
get_model_cache_ttl,
|
76
|
+
get_cache_stats,
|
77
|
+
clear_all_caches
|
78
|
+
)
|
79
|
+
|
80
|
+
# Check ujson availability for performance optimization
|
81
|
+
try:
|
82
|
+
import ujson
|
83
|
+
HAS_UJSON = True
|
84
|
+
UJSON_VERSION = getattr(ujson, '__version__', 'unknown')
|
85
|
+
except ImportError:
|
86
|
+
ujson = None
|
87
|
+
HAS_UJSON = False
|
88
|
+
UJSON_VERSION = None
|
89
|
+
|
90
|
+
# Main exports
|
91
|
+
__all__ = [
|
92
|
+
# Backend classes
|
93
|
+
'CacheBackend',
|
94
|
+
'MemoryCacheBackend',
|
95
|
+
'RedisCacheBackend',
|
96
|
+
'DisabledCacheBackend',
|
97
|
+
|
98
|
+
# Factory functions
|
99
|
+
'get_cache_backend',
|
100
|
+
'create_cache_backend',
|
101
|
+
'reset_cache_backend',
|
102
|
+
|
103
|
+
# Backend management
|
104
|
+
'get_available_backends',
|
105
|
+
'test_backend_connectivity',
|
106
|
+
'get_cache_health',
|
107
|
+
'validate_cache_config',
|
108
|
+
|
109
|
+
# Utilities
|
110
|
+
'get_cache_key',
|
111
|
+
'get_model_cache_ttl',
|
112
|
+
'get_cache_stats',
|
113
|
+
'clear_all_caches',
|
114
|
+
|
115
|
+
# Performance info
|
116
|
+
'HAS_UJSON',
|
117
|
+
'UJSON_VERSION',
|
118
|
+
]
|
119
|
+
|
120
|
+
# Version info
|
121
|
+
__version__ = "1.0.0"
|