Skip to main content

HTTP + WebSocket middleware for multi-tenant Django projects

Project description

django-multitenant-middleware

django-multitenant-middleware is a Django package that provides multi-tenant support for both HTTP and WebSocket (Channels) requests. It resolves tenants dynamically based on subdomains, hostnames, or custom headers.


Installation

pip install django-multitenant-middleware

Settings Configuration (HTTP)

  1. Define your tenant model in settings.py:
CHANNELS_MULTITENANT_TENANT_MODEL = "tenants.Client"  ## your tenant model

# Optional: Custom resolver class and args
CHANNELS_MULTITENANT_RESOLVER_CLASS = None  # defaults to FlexibleSubdomainTenantResolver
CHANNELS_MULTITENANT_RESOLVER_ARGS = {"base_domain": BASE_DOMAIN}
  1. Add the middleware to your Django MIDDLEWARE list:
MIDDLEWARE = [
    # Other middleware...
    "django_multitenant_middleware.http_middleware.TenantHTTPMiddleware",
]

The middleware automatically sets request.tenant and request.tenant_context.


WebSocket Integration (ASGI)

  1. In asgi.py:
import os
import django
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from django.core.asgi import get_asgi_application

from django_multitenant_middleware.ws_middleware import TenantWebSocketMiddleware
from django_multitenant_middleware.resolvers import FlexibleSubdomainTenantResolver
  1. Setup ASGI:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings") ## your django settings
django.setup()
django_asgi_app = get_asgi_application()
  1. Configure tenant resolver:
resolver = FlexibleSubdomainTenantResolver(
    base_domain="app.example.com",  # your base domain
    separators=("-", ".")
)
  1. Wrap WebSocket routes:
application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": TenantWebSocketMiddleware(
        AuthMiddlewareStack(
            URLRouter(websocket_urlpatterns)
        ),
        tenant_model=Client,  # your tenant model
        resolver=resolver,
    ),
})

Tenant Resolvers

  • FlexibleSubdomainTenantResolver: Extracts tenant from subdomain prefixes Example: tenant1-app.example.com → tenant1

  • HeaderTenantResolver: Extracts tenant from a custom HTTP header Example: X-Tenant-ID: tenant1 → tenant1

  • Custom Resolver: Subclass BaseTenantResolver to implement your logic

from channels_multitenant.resolvers import BaseTenantResolver

class MyCustomResolver(BaseTenantResolver):
    def resolve(self, scope) -> str | None:
        # Implement your custom logic
        return "my_tenant"

TenantFetcher (Optional Helper)

TenantFetcher provides async caching for WebSocket tenants:

from channels_multitenant.tenant_fetcher import TenantFetcher
from tenants.models import Client # your tenant model

fetcher = TenantFetcher(Client)
tenant = await fetcher.get_tenant("tenant1")
  • Caches tenants (default 5 minutes)
  • Async-ready for Channels

Notes

  • Ensure CHANNELS_MULTITENANT_TENANT_MODEL points to your tenant model.
  • Missing or invalid settings will raise ImproperlyConfigured.
  • Compatible with Django 4.x+ and Channels 3.x+.

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_multitenant_middleware-0.1.5.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

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

django_multitenant_middleware-0.1.5-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file django_multitenant_middleware-0.1.5.tar.gz.

File metadata

File hashes

Hashes for django_multitenant_middleware-0.1.5.tar.gz
Algorithm Hash digest
SHA256 db7644082b7d3252df1d72213b65b9f51077a11df0e4d8750200c14f481c45cf
MD5 7c04495f7264b006630a5df8c95bb3a2
BLAKE2b-256 bb3dad6d9bfb3186f65025ea5be67e292b75fc53becd5d0072e2745d33fb9d42

See more details on using hashes here.

File details

Details for the file django_multitenant_middleware-0.1.5-py3-none-any.whl.

File metadata

File hashes

Hashes for django_multitenant_middleware-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 d43c31c90fc817c7cc45ae359270b5e4bab444f45cc1d22b9b5ac13ba6d3e597
MD5 fa0f2057a4fe40d4aba38341b581ecd7
BLAKE2b-256 119ea849063ccd002a5612d36533a77b869e041b02089116e3ad0e8f1f120d5c

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