Skip to main content

Basic throttling app for Django

Project description

django-throttling is a an attempt at creating a simple app that allows to apply frequency limits to user’s requests.

Features

  • per-view maintenance mode

  • per-view timeouts

  • view disabling

  • timeouts are configured with respect to request.method

  • redirects

  • custom congestion views

  • view timeouts support callbacks

Requirements

  • django cache

Installation

Download django-throttling using one of the following methods:

pip

pip install django-throttling

Checkout from GitHub

Use one of the following commands:

git clone http://github.com/night-crawler/django-throttling.git

Configuration

Add ‘django_throttling’ into INSTALLED_APPS in settings.py:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    ...
    'django_throttling',
    ...
)

MIDDLEWARE

Add django_throttling.middleware.ThrottleMiddleware to your MIDDLEWARE_CLASSES in settings.py. You may need ‘request.user’ or ‘request.session’, etc., so insert it in a right place according to your needs.

SETTINGS

  • DJANGO_THROTTLING_ENABLED: enables ‘django-throttling’. Default is False.

  • DJANGO_THROTTLING_CACHE_EXPIRE: how long should we keep last_access time. If you set a large timeout for view, i.e. 24h, make sure that DJANGO_THROTTLING_CACHE_EXPIRE is not less than your timeout. Default is 60*60

  • DJANGO_THROTTLING_CACHE_PREFIX: a cache prefix for keys. Default is THROTTLING

  • THROTTLING_CACHE_KEY_PATTERNS: a dict with patterns for building the cache keys. May be redefined in app settings. Defaults are:

    • view_method: cache key pattern for a view with a method specified. Default pattern: %(prefix)s:%(view)s:%(uid)s:%(ip)s:%(method)s

    • view: cache key pattern for a view. Default pattern: %(prefix)s:%(view)s:%(uid)s:%(ip)s

    • site_method: cache key pattern for a whole site with a method. Default pattern: %(prefix)s:%(uid)s:%(ip)s:%(method)s

    • site: a global pattern. Default: %(prefix)s:%(uid)s:%(ip)s

  • DJANGO_THROTTLING_IGNORE_ADMINS: ignore throttling if user is admin. Default is True.

  • DJANGO_THROTTLING: a dict with app-path keys that configures the limits. I.e.: {'django.contrib.admin.options.change_view': {'all': 50, 'post': 5000}}

See Usage. For more.

Usage

Global fall-backs

Fall-back timeouts setup for any request at the current site:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 10000,
    'congestion': 'forum.views.congestion',
}

That stands for “one request per second, one POST request per 10s”. congestion is a view called after the throttle check, if it failes. It may be a uri, i.e. /forum/congestion/. Must uri start with ‘/’.

The simplest congestion view may look like:

def congestion(request, congestion_bundle):
    user = request.user
    progress = int(float(congestion_bundle['delta']) / congestion_bundle['timeout'] * 100)
    c = Context({'user': user, 'congestion_bundle': congestion_bundle, 'progress': progress})
    return render_to_response(get_theme_template(user, 'congestion.html'), c,
        context_instance=RequestContext(request)
    )

congestion_bundle is a dict, populated from a process_request():

congestion_bundle = {
    'view_func': self.view_func,
    'view_args': self.view_args,
    'view_kwargs': self.view_kwargs,
    'timeout': timeout,
    'delta': delta,
}

You may disable all POST’s on your site (‘maintenance mode’):

DJANGO_THROTTLING = {
    'all': 1000,
    'post': False,
    'congestion': 'forum.views.congestion',
}

In that case you will get HttpResponseBadRequest() on any POST.

Also, you may redirect your’s POST users to an any page:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': '/',
    'congestion': 'forum.views.congestion',
}

or you can use a custom maintenance view for it:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'forum.views.maintenance',
    'congestion': 'forum.views.congestion',
}

Maintenance view may look like:

def maintenance(request, maintenance_bundle):
    return HttpPreResponse(maintenance_bundle)

If you need a special cache key builder, or just to set a timeout is not enough for you, you can use a callback for, i.e., POST, that have to make it’s checks and return a tuple of cache key and one of the supported timeout types:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'callable:helpers.trash.my_callback',
    'congestion': 'forum.views.congestion',
}

And here’s the example callback:

def my_callback(request, view_func, view_args, view_kwargs):
    return 'some_strange_key_123', 10000

The full set of arguments the original view had is provided.

And don’t forget, that it is a fallback section, that used ONLY if you have no detailed rule for view throttling.

Per-view throttling

Per-view throttling is almost the same:

DJANGO_THROTTLING = {
    'all': 1000,
    'post': 'callable:helpers.trash.my_callback',
    'congestion': 'forum.views.congestion',

    'django.contrib.admin.options.change_view': {
        'post': False,
        'all': 0,
        'uri': '/admin/forum/post/23/',
        # 'post': 'callable:helpers.trash.my_callback',
        # 'all': 4000,
    },
}

First, it will disable all limits for django.contrib.admin.options.change_view. Then, it will disable the POST method for this view, ONLY if the request.path starts with ‘/admin/forum/post/23/’. Other options from global setup are permitted.

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-throttling-0.0.1.tar.gz (7.4 kB view hashes)

Uploaded Source

Supported by

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