Skip to main content

A REST framework for Django with secure DB-backed settings, REST/WebSocket support, jobs, auth, and more.

Project description

Django-MOJO

The full-stack Django framework for teams that want to ship, not assemble.


Most Django projects end up wiring together the same set of packages: a REST layer, an auth system, a job queue, a WebSocket server, a file store, a secrets manager, a metrics backend. Each one has its own conventions, its own config, its own failure modes — and none of them know about each other.

Django-MOJO ships all of that pre-integrated, with consistent patterns throughout. Define your models, configure permissions, and you have a production-grade API. The rest is already there when you need it.


What You Get

You used to wire up... Django-MOJO ships...
DRF + serializers + viewsets Model-first REST with RestMeta — permissions, graphs, filtering, pagination built in
SimpleJWT + django-allauth + MFA library Complete auth stack: JWT, OAuth, TOTP, passkeys, API keys, device management, session control
Channels + custom routing WebSocket pub/sub realtime — same auth as HTTP, topic-based, zero extra config
Celery + Redis Async job queue with scheduling, retries, heartbeat, and a web API
django-storages + custom S3 wrappers File upload, S3 backend, renditions, and an encrypted file vault
python-decouple + HashiCorp Vault DB-backed encrypted settings — secrets stay out of your repo, update without restart
structlog + Sentry + custom alerting Request logging, security incident tracking, and alerting baked into the request cycle
InfluxDB client or custom Redis counters Redis-backed time-series metrics with group-scoped rollups
Twilio SDK + phone number logic PhoneHub — SMS sending, phone normalization, test-number shortcuts

Install

pip install django-mojo

Quick Start

1. Define your model:

from django.db import models
from mojo.models import MojoModel

class Article(models.Model, MojoModel):
    title = models.CharField(max_length=200)
    body = models.TextField()
    author = models.ForeignKey("account.User", on_delete=models.CASCADE)
    is_published = models.BooleanField(default=False)

    class RestMeta:
        VIEW_PERMS = ["view_articles"]
        SAVE_PERMS = ["manage_articles"]
        LIST_DEFAULT_FILTERS = {"is_published": True}
        GRAPHS = {
            "default": {"fields": ["id", "title", "created"]},
            "detail":  {"fields": ["id", "title", "body", "author", "created"]},
        }

2. Expose it as a REST endpoint:

from mojo import decorators as md
from .models.article import Article

@md.URL('article')
@md.uses_model_security(Article)
def on_article(request, pk=None):
    return Article.on_rest_request(request, pk)

That's it. You now have list, retrieve, create, update, and delete — with object-level permissions, graph-controlled output, filtering, pagination, and auth — all from two files.


Authentication Out of the Box

Django-MOJO ships a complete auth stack. Nothing to install or wire up separately.

  • JWT — access + refresh tokens, configurable TTLs, device-aware
  • OAuth — Google, Apple, and extensible to any provider
  • TOTP — authenticator apps, backup codes, recovery flow
  • Passkeys — WebAuthn discoverable credentials
  • API Keys — per-user, revocable, scoped
  • Sessions — list and revoke active sessions
  • Security events — login history, suspicious activity, lockout guard
# Login — returns JWT access + refresh tokens
POST /api/account/login
{"username": "user@example.com", "password": "..."}

# All auth flows use the same bearer token middleware
Authorization: Bearer <token>

Secure Settings

Secrets belong in the database, not in your repo. Django-MOJO's settings helper reads from a lookup chain: Redis cache → DB (group-scoped → global) → Django file settings.

from mojo.helpers.settings import settings

# Static config — read from file, safe at import time
HEADER = settings.get_static("DUID_HEADER", "x-mojo-duid")

# Dynamic secrets — read from DB/Redis at call time
def send_sms(to, body):
    sid   = settings.get("TWILIO_ACCOUNT_SID", kind="str")
    token = settings.get("TWILIO_AUTH_TOKEN",  kind="str")
    ...

DB-backed settings activate automatically once Django is ready — no manual flag, no restart required to pick up changes.


Async Jobs

from mojo.apps.jobs import queue_job

# Queue a background task
queue_job("send_welcome_email", user_id=user.pk)

# Define the handler
from mojo.apps.jobs import job_handler

@job_handler("send_welcome_email")
def handle_welcome_email(job):
    user = User.objects.get(pk=job.data["user_id"])
    ...

Built-in: priority channels, retries with backoff, idempotency keys, scheduled jobs, worker heartbeat, and a REST API for job status.


Realtime WebSockets

# Client subscribes to a topic
ws.send({"action": "subscribe", "topic": "user:123"})

# Server pushes to a topic from anywhere
from mojo.apps.realtime import publish
publish("user:123", {"type": "notification", "message": "You have a new message"})

Same JWT authentication as HTTP. No extra config.


Project Layout

mojo/
├── apps/
│   ├── account/     # Users, groups, auth (JWT, OAuth, TOTP, passkeys, API keys)
│   ├── jobs/        # Async job queue and scheduler
│   ├── realtime/    # WebSocket pub/sub (Django Channels)
│   ├── fileman/     # File upload, S3 backend, renditions
│   ├── filevault/   # Encrypted file vault
│   ├── logit/       # Request + database logging
│   ├── incident/    # Security incident tracking and alerting
│   ├── metrics/     # Redis-backed time-series metrics
│   ├── phonehub/    # SMS and phone number management
│   ├── shortlink/   # URL shortening
│   ├── docit/       # Wiki and documentation pages
│   └── aws/         # SES email, SNS, S3 helpers
├── helpers/
│   ├── settings/    # DB-backed settings with encryption
│   ├── crypto/      # Signing, hashing, token generation
│   ├── logit/       # Structured logging
│   ├── geoip/       # IP geolocation and threat detection
│   ├── content_guard/ # Deterministic content moderation
│   └── ...          # dates, redis, request, response, paths, and more
├── middleware/      # CORS, auth, request logging
├── models/          # MojoModel, RestMeta base classes
├── serializers/     # Serialization engine and cache
└── rest/            # OpenAPI, decorators, routing

Documentation

Docs are organized by audience and optimized for both human developers and AI coding assistants.

Django Developer Reference

For developers building applications with Django-MOJO.

Section Description
Core MojoModel, REST framework, decorators, middleware, serialization
Helpers logit, dates, settings, crypto, request, redis, and other utilities
Account User, Group, JWT auth, OAuth, TOTP, passkeys, API keys, sessions
Logging Database logging, security incidents
Files File upload, storage backends, renditions
Email AWS SES email, templates, inbound handling
Jobs Async task queue
Metrics Redis-backed time-series metrics
Realtime WebSocket pub/sub
PhoneHub Phone number management and SMS
FileVault Encrypted file vault
DocIt Documentation and wiki system

REST API Reference

For frontend and mobile developers integrating with Django-MOJO APIs.

Section Description
Core Authentication, request format, filtering, pagination, graphs
Account Login, users, groups, API keys
Logging Log queries, incident management
Files File uploads and downloads
Email Templates, mailboxes
Jobs Job status
Metrics Time-series metrics
Realtime WebSocket protocol
PhoneHub Phone lookup and normalization
FileVault Encrypted file vault
DocIt Documentation pages

Migrating from django-nativemojo

If you currently have django-nativemojo installed, switch with no code changes — your imports are unchanged.

pip uninstall django-nativemojo
pip install django-mojo

The old package name remains available as a compatibility shim for existing deployments.


Contributing

Pull requests and issues are welcome. Contributions should follow the Developer Guide and keep to the framework's philosophy: explicit over magic, secure by default, conventions over configuration.


License

Licensed under the MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django_mojo-1.1.25.tar.gz (2.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_mojo-1.1.25-py3-none-any.whl (1.1 MB view details)

Uploaded Python 3

File details

Details for the file django_mojo-1.1.25.tar.gz.

File metadata

  • Download URL: django_mojo-1.1.25.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for django_mojo-1.1.25.tar.gz
Algorithm Hash digest
SHA256 25bca20ab62c0a84ffa740a43046decefe8c84a2bef51baae15952e1e99bf16b
MD5 9c50f2286cb7c20e2d29773a2a5172c2
BLAKE2b-256 6a655b4a60a5237d854d591291d969b8e18b0cbf5d0120ad1dcd8c2385444b02

See more details on using hashes here.

File details

Details for the file django_mojo-1.1.25-py3-none-any.whl.

File metadata

  • Download URL: django_mojo-1.1.25-py3-none-any.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for django_mojo-1.1.25-py3-none-any.whl
Algorithm Hash digest
SHA256 89ce4393d4f9d8f5206ea511e0ccc27e42ade84bfcf6d7465fffbe33c189f144
MD5 9566ae5c944ca128a8df1bb49d0593ad
BLAKE2b-256 dca81b5c579701e67d08969920debc705cf030fc58c13605e951ece76622357b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page