This is a implementation of Cap.js Server for Django, which provides challenge generation and verification for PoW (Proof of Work) captcha. See
To install the package, simply run:
pip install django-capIf you want to use the Django Ninja integration, you can install it with:
pip install django-cap[ninja]Or if you want to use the Django Rest Framework integration, you can install it with:
pip install django-cap[drf]TODO: only ninja integration and vanilla Django Json views are implemented, DRF integration will be added in the future.
To use this package, you need to add django_cap to your INSTALLED_APPS in your Django settings file:
INSTALLED_APPS = [
...
'django_cap',
'django_cap.ninja', # Add this if you want enable ninja integration
]You need to configure the url patterns in your Django project's urls.py file:
from django_cap.example_views import urls as example_views_urls
# import examples if you want to see them
urlpatterns = [
...
path("cap/", include("django_cap.urls")),
path("cap/examples/", include("django_cap.example.urls")),, # add this if you want to see examples
...
]You can access the api at /cap/v1/[challenge|redeem|validate] endpoints. This is compatible with Cap.js/widgets. If your frontend is not hosted by Django, you need to refer Cap.js documentation for the installation, and simply configure the api endpoint as following:
<cap-widget id="cap" data-cap-api-endpoint="https://your-api-site/cap/v1/"></cap-widget>By default, ninja doc will be avaliable at /cap/v1/docs/ and /cap/v1/openapi.json. If you want to disable the ninja doc, you can disable it in your Django settings file:
#django_settings.py
...
CAP_NINJA_API_ENABLE_DOCS = False
...This package provides comprehensive Django form integration for CAP verification. You can easily add CAP verification to any Django form:
- Add
CapFieldto your form:
from django import forms
from django_cap.forms import CapField
class MyForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
# Add CapField for CAP verification
cap_token = CapField(help_text="Please retry the verification challenge.")- In your template, render the form as usual:
<form method="post">
{% csrf_token %}
{{ form.name.label_tag }} {{ form.name }}
{{ form.email.label_tag }} {{ form.email }}
{{ form.cap_token.label_tag }} {{ form.cap_token }}
{% if form.cap_token.errors %}
<div class="form-errors">
{% for error in form.cap_token.errors %}<div class="error">{{ error }}</div>{% endfor %}
</div>
{% endif %}
<button type="submit">Submit</button>
</form>That's it! The CapField will automatically handle the CAP verification process, including generating the challenge and validating the response.
CAP_NINJA_API_ENABLE_DOCS: Enable or disable the ninja API docs. Default isTrue.CAP_CHALLENGE_COUNT: The number of answer required for one challenge. Default is 50.CAP_CHALLENGE_SIZE: The size of the challenge string. Default is 32.CAP_CHALLENGE_DIFFICULTY: The difficulty of the challenge, Default is 4CAP_CHALLENGE_EXPIRES_S: The expiration time of the challenge in seconds. Default is 30 seconds.CAP_TOKEN_EXPIRES_S: The expiration time of the token in seconds. Default is 10 minutes.CAP_CLEANUP_INTERVAL_S: The interval for cleaning up expired challenges and tokens in seconds. Default is 60 seconds.
-
Clone this repository.
-
Make sure you have python 3.13 installed.
python --version
-
Make sure you have uv installed.
# for MacOS, recommend using homebrew brew install uv# for Linux, recommend using their installer # curl curl -LsSf https://astral.sh/uv/install.sh | sh # wget wget -qO- https://astral.sh/uv/install.sh | sh
# for Windows, recommend using WinGet winget install --id=astral-sh.uv -e # you can also use scoop scoop install main/uv
-
Install the dependencies:
uv sync
-
Activate the virtual environment:
# for linux/macOS source .venv/bin/activate
# for windows .\.venv\Scripts\Activate.ps1 -
Run tests:
uv run pytest
-
Run linting and formatting:
# Check code quality uv run ruff check # Format code uv run ruff format
-
Build the package:
uv run pdm build
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.