bashu / django-maintenancemode Goto Github PK
View Code? Open in Web Editor NEW๐ django-maintenancemode allows you to temporary shutdown your site for maintenance work
License: BSD 3-Clause "New" or "Revised" License
๐ django-maintenancemode allows you to temporary shutdown your site for maintenance work
License: BSD 3-Clause "New" or "Revised" License
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
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.
Hi there!
You forgot to include CHANGES file in tarball, so setup.py fail on build.
Thanks.
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:
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)
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?
I have a few suggestions on how to improve this package. Is this package still maintained?
The current default for the lockfile uses the file location of the distributed conf.py file.
The resulting location can be under /usr/local or /usr/lib and not writable.
I'm still on Django 1.6, but I don't think it will be different in later version.
Having the tests to run locally too make sure things are correct in the local environment would be nice.
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.
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)
Make sure example
project works without PYTHONPATH
manipulations
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?
It would be a nice feature
README.rst and CHANGES are not available when installing from django-maintenancemode-0.10.tar.gz
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.
Hi,
I am running jobs on travis-ci but its been found that job is failing for python 2.7.
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
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.
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'
)
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?
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
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.
i.e.:
INTERNAL_IPS = [
'10.10.10.0/24',
]
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?
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.