Code Monkey home page Code Monkey logo

django-maintenancemode's Introduction

There's nothing to see here. Move along. Keep moving.

django-maintenancemode's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-maintenancemode's Issues

This project needs a maintainer.

Hi,

This repository seems to lack maintenance, I propose myself as a new maintainer.

Could you give me the right to push in your repository or just transfer it on my account in github?

Thank you

Compliance with Django 1.10 middleware

The module don't work with newer versions of Django from 1.10, because of the changes in Middleware introduced in 1.10 โ€”see documentation.

As said in the documentation I've tested to change the 'middleware.py' file, making 'MaintenanceModeMiddleware' inherit from 'django.utils.deprecation.MiddlewareMixin' instead of 'object' and everything seems fine now. It works like a charm.

Better customization

Hi @bashu

I'm thinking about using a settings object that reads from a dict in django settings. Something like https://github.com/encode/django-rest-framework/blob/master/rest_framework/settings.py

What do you think?

This is because we could try and provide more configuration details such as:

  1. return json instead of html, with custom message
  2. custom methods for bypassing the maintenance mode
  3. turning on/off the methods used in processing the request

This is our current setup:

import re
from abc import abstractmethod
from typing import Type

import django
from django.conf import settings, urls
from django.core.exceptions import MiddlewareNotUsed
from django.http import HttpRequest, JsonResponse
from django.urls import get_resolver, resolvers
from django.utils.deprecation import MiddlewareMixin

from feature_flags import FlagKeys, get_variation


# Borrowed heavily from https://github.com/shanx/django-maintenancemode
# TODO: push the changes here to the repo as contributions.

IGNORE_URLS = tuple(re.compile(u) for u in settings.MAINTENANCE_IGNORE_URLS)


class BaseExclusionHandler:
    def __init__(self, request: HttpRequest):
        self.request = request

    @abstractmethod
    def should_bypass(self) -> bool:
        raise NotImplementedError


class LDExclusionHandler(BaseExclusionHandler):
    def should_bypass(self) -> bool:
        return get_variation(
            FlagKeys.should_bypass_maintenance_mode,
            user_obj=self.request.user,
            default_behavior=False,
            extra_attrs=dict(path=self.request.path_info),
        )


def temporary_unavailable(request):  # noqa
    return HttpResponseTemporaryUnavailable(
        dict(
            message="We will be back soon.",  # TODO: load message from FormSettings
        )
    )


# todo: move to package settings
response_class = JsonResponse  # could also be HttpResponse
exclusion_handler: Type[BaseExclusionHandler] = LDExclusionHandler  # todo: make this a list of handlers
return_view = temporary_unavailable

urls.handler503 = return_view
urls.__all__.append("handler503")


class HttpResponseTemporaryUnavailable(response_class):
    status_code = 503


class MaintenanceModeMiddleware(MiddlewareMixin):
    def __init__(self, get_response):
        if not settings.MAINTENANCE_MODE:
            raise MiddlewareNotUsed()

        super().__init__(get_response=get_response)

    @staticmethod
    def process_request(request: HttpRequest):
        # Allow access if middleware is not activated

        print(request.path_info)
        if exclusion_handler(request).should_bypass():
            return None

        # Check if a path is explicitly excluded from maintenance mode
        for url in IGNORE_URLS:
            if url.match(request.path_info):
                return None

        if django.__version__ < "3.2":
            # Checks if DJANGO version is less than 3.2.0 for breaking change
            resolver = get_resolver()

            callback, param_dict = resolver.resolve_error_handler("503")

            return callback(request, **param_dict)

        else:
            # Default behaviour for django 3.2 and higher
            resolver = resolvers.get_resolver(None)
            resolve = resolver.resolve_error_handler
            callback = resolve("503")

            return callback(request)

503 causes pingdom alert

This is more of a question than a problem. Do you have any suggestion on how to not come across as being down?

By using maintenance mode my site is still functioning as expected and should not come across as an error. Is there a way to change the status code to 200, for example?

Management command does not work for Heroku

This is not a bug but a limitation of the current system. That is heroku depoloyments cannot benefit from the approach being used with the management on|off command.

Any execution of heroku run manage.py will be run on a separate worker dyno, not the web one. Therefore the lockfile is set but on the wrong machine.

It would be nice to have a dynamic approach that works for Heroku. It seems like the most obvious thing is to maintain the flag in a DB table instead of in the filesystem.

Another possible workaround is providing a a staff-authenticated URL route which togged the maintenance status by adding/removing the file.

limit staff users too!

current implementation let's any staff user access pages (link)

if hasattr(request, 'user') and request.user.is_staff:
    return None

I think it would better to have a custom queryset to limit some staff users, or at least fully disable access for all user (staff or not staff)

Package Management + Coding Style

What do you think about using poetry in the project?

Also, what do you think about using a pre-commit to enforce a coding style such as Black?

0.10 setup.py fails

README.rst and CHANGES are not available when installing from django-maintenancemode-0.10.tar.gz

Release 0.11.8 ?

Hi.

Is there any plan to release version 0.11.8 soon ?
I'm a bit stuck with the issue solved in PR #40.

Thanks.

Job failing on travis-ci for python 2.7

Hi,
I am running jobs on travis-ci but its been found that job is failing for python 2.7.

Log:
Setting environment variables from .travis.yml
$ export DJANGO="Django>=1.11,<1.12"
0.01s$ source ~/virtualenv/python2.7/bin/activate
$ python --version
Python 2.7.15
$ pip --version
pip 20.1.1 from /home/travis/virtualenv/python2.7.15/lib/python2.7/site-packages/pip (python 2.7)
before_install
7.91s$ pip install -q $DJANGO coveralls
install
0.59s$ python setup.py develop
2.33s$ python setup.py test
running test
WARNING: Testing via this command is deprecated and will be removed in a future version. Users looking for a generic test entry point independent of test runner are encouraged to use tox.
/home/travis/virtualenv/python2.7.15/lib/python2.7/site-packages/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
from cryptography import x509
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
/home/travis/virtualenv/python2.7.15/lib/python2.7/site-packages/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
from cryptography import x509
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. pip 21.0 will drop support for Python 2.7 in January 2021. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
running egg_info
writing requirements to django_maintenancemode.egg-info/requires.txt
writing django_maintenancemode.egg-info/PKG-INFO
writing top-level names to django_maintenancemode.egg-info/top_level.txt
writing dependency_links to django_maintenancemode.egg-info/dependency_links.txt
reading manifest file 'django_maintenancemode.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'django_maintenancemode.egg-info/SOURCES.txt'
running build_ext
Creating test database for alias 'default'...
maintenancemode.tests (unittest.loader.ModuleImportFailure) ... ERROR
Destroying test database for alias 'default'...
Coverage Report:
Name Stmts Miss Cover

maintenancemode/conf.py 10 7 30%
maintenancemode/http.py 3 3 0%
maintenancemode/management/commands/maintenance.py 20 20 0%
maintenancemode/middleware.py 32 32 0%
maintenancemode/models.py 0 0 100%
maintenancemode/utils.py 25 23 8%
maintenancemode/views.py 11 11 0%

TOTAL 101 96 5%
PEP8 Report:
maintenancemode/middleware.py:23:80: E501 line too long (80 > 79 characters)
maintenancemode/tests.py:36:80: E501 line too long (85 > 79 characters)
maintenancemode/tests.py:50:80: E501 line too long (89 > 79 characters)
maintenancemode/tests.py:58:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:64:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:69:80: E501 line too long (82 > 79 characters)
maintenancemode/tests.py:75:80: E501 line too long (100 > 79 characters)
maintenancemode/tests.py:77:80: E501 line too long (93 > 79 characters)
maintenancemode/tests.py:78:80: E501 line too long (88 > 79 characters)
maintenancemode/tests.py:84:80: E501 line too long (100 > 79 characters)
maintenancemode/tests.py:86:80: E501 line too long (93 > 79 characters)
maintenancemode/tests.py:95:80: E501 line too long (100 > 79 characters)
maintenancemode/tests.py:97:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:106:80: E501 line too long (131 > 79 characters)
maintenancemode/tests.py:108:80: E501 line too long (93 > 79 characters)
maintenancemode/tests.py:117:80: E501 line too long (135 > 79 characters)
maintenancemode/tests.py:119:80: E501 line too long (93 > 79 characters)
maintenancemode/tests.py:128:80: E501 line too long (131 > 79 characters)
maintenancemode/tests.py:130:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:136:80: E501 line too long (90 > 79 characters)
maintenancemode/tests.py:139:80: E501 line too long (80 > 79 characters)
maintenancemode/tests.py:141:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:146:80: E501 line too long (84 > 79 characters)
maintenancemode/tests.py:148:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:153:80: E501 line too long (100 > 79 characters)
maintenancemode/tests.py:156:80: E501 line too long (94 > 79 characters)
maintenancemode/tests.py:161:80: E501 line too long (101 > 79 characters)
maintenancemode/tests.py:163:80: E501 line too long (109 > 79 characters)
maintenancemode/tests.py:166:80: E501 line too long (110 > 79 characters)
maintenancemode/views.py:16:1: E402 module level import not at top of file

ERROR: maintenancemode.tests (unittest.loader.ModuleImportFailure)

ImportError: Failed to import test module: maintenancemode.tests
Traceback (most recent call last):
File "/opt/python/2.7.15/lib/python2.7/unittest/loader.py", line 254, in _find_tests
module = self._get_module_from_name(name)
File "/opt/python/2.7.15/lib/python2.7/unittest/loader.py", line 232, in _get_module_from_name
import(name)
File "/home/travis/build/kishorkunal-raj/django-maintenancemode/maintenancemode/tests.py", line 16, in
from maintenancemode import utils File "/home/travis/build/kishorkunal-raj/django-maintenancemode/maintenancemodeutils.py", line 5, in
from .conf import settings
File "/home/travis/build/kishorkunal-raj/django-maintenancemode/maintenancemode/conf.py", line 6, in from appconf import AppConf
File "/home/travis/virtualenv/python2.7.15/lib/python2.7/site-packages/django_appconf-1.0.4-py2.7.egg/appconf/init.py", line 1, in
from .base import AppConf # noqa
File "/home/travis/virtualenv/python2.7.15/lib/python2.7/site-packages/django_appconf-1.0.4-py2.7.egg/appconf/base.py", line 107
class AppConf(metaclass=AppConfMetaClass):
^
SyntaxError: invalid syntax

Ran 1 test in 0.069s
FAILED (errors=1)
Test failed: <unittest.runner.TextTestResult run=1 errors=1 failures=0>
error: Test failed: <unittest.runner.TextTestResult run=1 errors=1 failures=0>
trThe command "python setup.py test" exited with 1.

Please look into it

Handling of multilingual sites

It'd be a nice feature if the module could handle automatically the prefixes of the languages in multilingual sites, using them to prefix the ignored urls.

Ignore URLs not working

I'm using this neat little package in my project and it works like a charm except for the ignore URL feature. When i add any ignore URLs it seems to default to not redirecting to the 503 page at all. When i remove the MAINTENANCE_IGNORE_URLS variable everything works as expected again. This is on Django 1.3.1 and my middleware order looks like this (since that might have something to do with it?)

MIDDLEWARE_CLASSES = (
    #'raven.contrib.django.middleware.SentryResponseErrorIdMiddleware',
    #'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.http.ConditionalGetMiddleware',
    'django.middleware.gzip.GZipMiddleware',
    'maintenancemode.middleware.MaintenanceModeMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
    #'raven.contrib.django.middleware.Sentry404CatchMiddleware'
)

Unknown command: 'maintenance' - setup problems

Just trying this out, and pip installed the hot new version 0.11. But I can't tell that it's working at all? I feel like I'm making a rookie mistake but the instructions are so simple.

This shows what I've done:

(mm)...]$ pip freeze | grep maintenance
django-maintenancemode==0.11.0

(mm)...]$ git diff .
diff --git a/mysite/mysite/settings/base.py b/mysite/mysite/settings/base.py
index 863ab39..7e0f61e 100644
--- a/mysite/mysite/settings/base.py
+++ b/mysite/mysite/settings/base.py
@@ -124,12 +124,26 @@ MIDDLEWARE_CLASSES = (
     'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'maintenancemode.middleware.MaintenanceModeMiddleware', # after Auth. Middleware
     'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 )

+# Setting this variable to ``True`` activates the middleware.
+# But can also activate: python ./manage.py maintenance <on|off>
+MAINTENANCE_MODE = True
+
+# Sequence of URL path regexes to exclude from the maintenance mode.
+# Default: ()
+# TODO: could put /resources here, etc. and probably anything that doesn't 
+# really depend on the database.
+#MAINTENANCE_IGNORE_URLS = (
+#    r'^/docs/.*',
+#    r'^/contact'
+#)
+

(mm)...]$ ./manage.py maintenance on
Unknown command: 'maintenance'
Type 'manage.py help' for usage.

I also tried migrating, not that I expected it needed it.

What's going on?

django 1.8 compatibility

Hi guys,

I tried to use the plugin with django 1.8. I get the following exception. When using django 1.7.7 everything works fine:

AttributeError: 'RegexURLResolver' object has no attribute '_resolve_special'

Exception

Stacktrace (most recent call last):

File "maintenancemode/middleware.py", line 44, in process_request
callback, param_dict = resolver._resolve_special('503')

Best,
Ron

Adding messages

Great module, I've used it for years.

Just want to suggest a new feature -- adding a message to contrib.messages via settings, as sometimes you may want to give more details to site visitors about the reason of the maintenance and how long it would last.

Middleware early return refactor (suggest/request for comment)

https://github.com/shanx/django-maintenancemode/blob/6555e4afd9ade091a8538b1a0b2b63cff1c86d25/maintenancemode/middleware.py#L54-L66

Don't need to else section due to early return. It's can refactor like:

 if DJANGO_VERSION_MAJOR >= 3 and DJANGO_VERSION_MINOR >= 2: 
     # Checks if DJANGO version is great than 3.2.0 for breaking change 
     resolver = resolvers.get_resolver(None) 
     resolve = resolver.resolve_error_handler 
     callback = resolve('503') 
     return callback(request)

 resolver = get_resolver() 
 callback, param_dict = resolver.resolve_error_handler("503") 
 return callback(request, **param_dict) 

Maybe it's not enough "readable". What do you think about this?

Check on maintenance status

Yan you please help me on how to check the status that the site is in. I recently forgot to turn off maintenance mode. I would like to see it even as an admin, that the site is currently in maintenance mode, but I could not figure out how to get the status.

This is what I tried:
>>> from maintenancemode import utils as maintenance
>>> maintenance.status
Traceback (most recent call last):
File "", line 1, in
AttributeError: 'module' object has no attribute 'status'

What did I do wrong?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.