{"id":8121,"library":"django-watchman","title":"Django Watchman","description":"django-watchman exposes a status endpoint for your backing services like databases, caches, and other services. It is currently at version 1.5.0 and maintains an active release cadence with regular updates and security fixes.","status":"active","version":"1.5.0","language":"en","source_language":"en","source_url":"https://github.com/mwarkentin/django-watchman","tags":["django","health check","monitoring","status","liveness","readiness"],"install":[{"cmd":"pip install django-watchman","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"As a Django pluggable application, it requires Django to function. Supports Django 4.2, 5.1, and 5.2.","package":"Django","optional":false},{"reason":"Requires Python >=3.10.","package":"Python","optional":false}],"imports":[{"note":"For modern Django versions, `re_path` should be used instead of `url`. The `include` function remains the standard way to incorporate URL configurations.","wrong":"from django.conf.urls import url, include # url() is deprecated in modern Django","symbol":"watchman.urls","correct":"from django.urls import re_path, include\n\nurlpatterns = [\n    re_path(r'^watchman/', include('watchman.urls')),\n]"},{"note":"Used for a minimal HTTP 200/500 response, typically for load balancers. You must wire this up manually in your `urls.py`.","symbol":"watchman.views.bare_status","correct":"from django.urls import path\nfrom watchman.views import bare_status\n\nurlpatterns = [\n    path('watchman/bare/', bare_status),\n]"}],"quickstart":{"code":"import os\n\n# settings.py\nINSTALLED_APPS = [\n    # ... other apps\n    'watchman',\n]\n\n# urls.py\nfrom django.urls import re_path, include\n\nurlpatterns = [\n    # ... other url patterns\n    re_path(r'^watchman/', include('watchman.urls')),\n    # For a minimal status endpoint (optional)\n    # from watchman.views import bare_status\n    # re_path(r'^watchman/bare/$', bare_status),\n]\n\n# Optional: Protect with a token (add to settings.py)\n# WATCHMAN_TOKEN = os.environ.get('WATCHMAN_TOKEN', 'your_secret_token')\n\n# Run checks from command line (optional)\n# python manage.py watchman -v 2","lang":"python","description":"To quickly integrate `django-watchman`, add 'watchman' to your `INSTALLED_APPS` and include `watchman.urls` in your project's `urls.py`. This will provide a JSON status endpoint at `/watchman/` and an HTML dashboard at `/watchman/dashboard/`. For a simpler liveness probe, the `/watchman/ping/` endpoint is also available."},"warnings":[{"fix":"Upgrade your Python environment to 3.10+ and Django to 2.0+ (preferably 4.2+), and remove `django-jsonview` from your dependencies if upgrading from pre-1.0.0 versions.","message":"Version 1.0.0 dropped support for Python 2 and Django versions older than 2.0. Additionally, it removed the dependency on `django-jsonview` in favor of Django's built-in `JsonResponse`.","severity":"breaking","affected_versions":"<1.0.0"},{"fix":"Ensure your `urls.py` uses `re_path(r'^watchman/', include('watchman.urls'))` for compatibility with Django 3.1+.","message":"Prior to version 1.3.0, `django-watchman` used `django.conf.urls.url()`. This function has been deprecated in modern Django versions (3.1+), which now primarily use `re_path()` or `path()`.","severity":"deprecated","affected_versions":"<1.3.0"},{"fix":"If you encounter `TypeError: 'str' object is not iterable` or `ImportError` related to `WATCHMAN_CHECKS`, change your setting from `WATCHMAN_CHECKS = 'single.check'` to `WATCHMAN_CHECKS = ('single.check',)` or `WATCHMAN_CHECKS = ['single.check']`.","message":"When configuring `WATCHMAN_CHECKS` in your settings, ensure it is a sequence (e.g., a list or a tuple), not a single string. For a tuple with one item, remember the trailing comma: `('my.custom.check',)`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Upgrade to `django-watchman` 1.5.0 or newer, which addresses this by using `SELECT 1 FROM DUAL` for Oracle.","message":"The database health check in `django-watchman` might fail for Oracle databases when using `SELECT 1` without a `FROM` clause.","severity":"gotcha","affected_versions":"<1.5.0"},{"fix":"Upgrade to `django-watchman` 1.4.0 or newer to mitigate the ReDoS vulnerability.","message":"Version 1.4.0 included a security fix for a Regular Expression Denial of Service (ReDoS) vulnerability in the Authorization header parsing. Crafted input could lead to polynomial backtracking.","severity":"gotcha","affected_versions":"<1.4.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Change `WATCHMAN_CHECKS = 'my.check'` to `WATCHMAN_CHECKS = ('my.check',)` (for a tuple) or `WATCHMAN_CHECKS = ['my.check']` (for a list).","cause":"The `WATCHMAN_CHECKS` setting in your Django `settings.py` is configured as a string instead of a sequence (list or tuple). This often happens when defining a single check without a trailing comma, e.g., `WATCHMAN_CHECKS = ('my.check')` instead of `WATCHMAN_CHECKS = ('my.check',)`.","error":"TypeError: 'str' object is not iterable"},{"fix":"Ensure the Watchman daemon is installed and running (`brew install watchman` on macOS, or follow OS-specific instructions). If it still times out for large projects, you may need to increase the timeout for `pywatchman` or configure Watchman to ignore certain directories (e.g., `node_modules`).","cause":"This error typically occurs during Django development server startup when `pywatchman` (used by Django's `WatchmanReloader` for file watching) cannot connect to the Watchman daemon within the default timeout. This is not directly from `django-watchman` but is a common adjacent issue when using Watchman for auto-reloading.","error":"Error connecting to Watchman: timed out waiting for response, while executing ('watch-project', 'my_app')"},{"fix":"Ensure `pywatchman` is correctly installed in your environment (`pip install pywatchman`) and that your Django project is properly set up to find and use it. In most cases, just having `pywatchman` installed is enough, but sometimes environment issues or conflicting settings can prevent its detection. Restarting your development server is often necessary.","cause":"You have `pywatchman` and `django-watchman` installed, but Django's development server is still using the default `StatReloader` instead of `WatchmanReloader` for file change detection. This means Watchman is not being utilized for faster reloads.","error":"Watching for file changes with StatReloader"},{"fix":"Verify that the database user, password, host, and port configured in your Django `settings.py` for the database connection are correct and have the necessary privileges to connect and perform a basic `SELECT` query.","cause":"The database check executed by `django-watchman` failed due to incorrect database credentials or permissions configured in your Django `DATABASES` settings.","error":"Database check failed: Access denied for user 'X'@'localhost' (using password: YES)"}]}